Gráfico de linha

Gráficos de linha são frequentemente usados para representar séries de tempo, isto é, valores que mudam ao longo do tempo. O ggplot oferce alguma variedade de opções para este fim, mas a mais comum é geom_line(). Este geom exige argumentos tanto para o eixo-x como para o eixo-y. Em geral, o eixo-x representa o tempo e o eixo-y o valor da variável de interesse. Este ponto pode parecer irrelevante, mas será importante para entender algumas das dificuldades em usar séries de tempo com o ggplot.

Abaixo temos a base economics, que traz a evolução de algumas variáveis econômicas ao longo do tempo. Note que há uma coluna com as datas.

Data Consumo População Poupança Tempo desempregado (semanas) Desemprego
1967-07-01 506.7 198712 12.6 4.5 2944
1967-08-01 509.8 198911 12.6 4.7 2945
1967-09-01 515.6 199113 11.9 4.6 2958
1967-10-01 512.2 199311 12.9 4.9 3143
1967-11-01 517.4 199498 12.8 4.7 3066
1967-12-01 525.1 199657 11.8 4.8 3018
1968-01-01 530.9 199808 11.7 5.1 2878
1968-02-01 533.6 199920 12.3 4.5 3001
1968-03-01 544.3 200056 11.7 4.1 2877
1968-04-01 544.0 200208 12.3 4.6 2709
1968-05-01 549.8 200361 12.0 4.4 2740
1968-06-01 556.3 200536 11.7 4.4 2938
1968-07-01 563.2 200706 10.7 4.5 2883
1968-08-01 567.0 200898 10.5 4.2 2768
1968-09-01 568.2 201095 10.6 4.6 2686

Para visualizar, por exemplo, o comportamento da taxa de poupança: definimos aes(x = date, y = psavert).

ggplot(data = economics, aes(x = date, y = psavert)) + geom_line()

head(economics)
## # A tibble: 6 x 6
##   date         pce    pop psavert uempmed unemploy
##   <date>     <dbl>  <dbl>   <dbl>   <dbl>    <dbl>
## 1 1967-07-01  507. 198712    12.6     4.5     2944
## 2 1967-08-01  510. 198911    12.6     4.7     2945
## 3 1967-09-01  516. 199113    11.9     4.6     2958
## 4 1967-10-01  512. 199311    12.9     4.9     3143
## 5 1967-11-01  517. 199498    12.8     4.7     3066
## 6 1967-12-01  525. 199657    11.8     4.8     3018

Outra opção é usar o geom_step() que torna mais claras as mudanças de nível como no exemplo abaixo.

recent <- economics[economics$date > as.Date("2012-01-01"), ]
ggplot(data = recent, aes(x = date, y = psavert)) + geom_step()

Por fim podemos plotar a evolução de duas variáveis no tempo usando geom_path.

ggplot(data = economics, aes(x = unemploy/pop, y = psavert)) + geom_path()

Um exemplo que talvez torne mais clara a funcionalidade desta função é o gráfico da Curva de Phillips. O pacote strucchange além de trazer funções para lidar com séries de tempo também traz a base de dados original da pesquisa do economista neo-zelandês William Phillips. Phillips encontrou originalmente uma relação entre a taxa de desemprego e a taxa de variação dos salários. Versões alternativas da Curva de Phillips costumam relacionar o desemprego à variações do nível de preços (inflação). O exemplo abaixo mostra esta relação no período 1913-1948.

library(strucchange)
data(PhillipsCurve)
sub <- window(PhillipsCurve, start = c(1913), end = c(1948))
dados <- data.frame(dp = sub[, 4],
                    u = sub[, 3],
                    tempo = 1913:1948)

ggplot(data = dados, aes(x = u, y = dp))+geom_path()+geom_text(aes(label = tempo))

Opções estéticas

Há três opções estéticas básicas para gráficos de linha:

  • colour - define a cor da linha
  • linetype - tipos diferentes de linhas
  • size - tamanho da linha

Pode-se, por exemplo, escolher uma linha tracejada no gráfico especificando linetype = 2.

ggplot(data = economics, aes(x = date, y = psavert)) + geom_line(linetype = 2)

O gráfico de linha padrão assume que linetype = 1. Há 12 tipos diferentes de linhas. Abaixo pode-se ver a diferença entre cada uma delas.

Para mudar a espessura da linha usa-se size. O padrão é size = 1

ggplot(data = economics, aes(x = date, y = psavert)) + geom_line(size = 2)

Para especificar a cor podemos fornecer um nome como string ou um hexcode.

ggplot(data = economics, aes(x = date, y = psavert))+geom_line(colour = "orange")

ggplot(data = economics, aes(x = date, y = psavert))+geom_line(colour = "#F08080")

Como de costume, as características estéticas do gráfico podem refletir grupos de variáveis. No caso abaixo cada grupo tem uma cor e um tipo de linha diferente.

x <- seq(0, 2*pi, 0.001)
seno <- sin(x)
cosseno <- cos(x)
grupo <- c(rep("a", length(x)), rep("b", length(x)))
dados <- data.frame(
    tempo = rep(x, 2),
    valor = c(seno, cosseno),
    grupo = grupo
    )

ggplot(dados, aes(x = tempo, y = valor, group = grupo)) +
  geom_line(aes(colour = grupo, linetype = grupo))

Combinando gráficos

A lógica do ggplot é de somar elementos a um gráfico inicial. Uma combinação possível é juntar geom_line() com o geom_point().

ggplot(data = economics, aes(x = date, y = psavert)) +
    geom_line() +
    geom_point()

O gráfico abaixo mostra como plotar a variação percentual do PIB trimestral (em colunas) e o desemprego (numa linha). Neste caso é preciso fazer alguma manipulação de dados para chegar na variação percentual do PIB contra o mesmo trimestre do ano anterior. Para diferenciar valores negativos de positivos crio um factor que funciona essencialmente como uma variável indicadora, i.e., uma variável que retorna 1 para valores positivos e 0 para valores negativos. As cores das colunas são escolhidas automaticamente pelo R (poderia ter especificado-as manualmente); a cor da linha foi escolhida como black. Note que mudo a cor da coluna especificando um valor para fill que escolhe a cor para preencher a coluna. Comento mais sobre este tipo de gráfico neste post

library(AER)
library(dplyr)
data("USMacroG")
d <- as.data.frame(USMacroG)
# Computa o variação percentual do PIB contra o mesmo trimestre do ano anterior
d <- d %>%
  mutate(
    diff_gdp = (gdp - lag(gdp, 4)) / lag(gdp, 4),
    expansao = as.factor(ifelse(diff_gdp > 0, 1, 0)),
    data = as.Date(time(USMacroG))
    )
# Filtra para as décadas de 70 e 80
sub <- d %>%
  filter(data > as.Date("1970-01-01") & data < as.Date ("1990-01-01"))

ggplot(sub, aes(x = data)) +
  geom_col(aes(y = diff_gdp * 100, fill = expansao)) +
  geom_line(aes(y = unemp, colour = "unemp"), size = 1) +
  scale_colour_manual(values = "black")

Usando o qplot

O R tem uma classe específica para séries de tempo chamado ts. A série AirPassengers, por exemplo, é interpretada como ts.

class(AirPassengers)
## [1] "ts"

Para visualizá-la usamos ou o plot ou o plot.ts

plot.ts(AirPassengers)

O qplot costuma funcionar segundo a mesma sintaxe do plot, como pode ser visto em exemplos passados. Mas neste caso há uma complicação pois, como visto acima, o geom_line usa dois argumentos (x, y), enquanto o plot só precisa de um. Isto acontece porque a função base do R assume implicitamente que o tempo será plotado no eixo-x. Para contornar este problema podemos usar a função time que extrai as datas de uma série de tempo como um vetor numérico.

time(AirPassengers)
##           Jan      Feb      Mar      Apr      May      Jun      Jul
## 1949 1949.000 1949.083 1949.167 1949.250 1949.333 1949.417 1949.500
## 1950 1950.000 1950.083 1950.167 1950.250 1950.333 1950.417 1950.500
## 1951 1951.000 1951.083 1951.167 1951.250 1951.333 1951.417 1951.500
## 1952 1952.000 1952.083 1952.167 1952.250 1952.333 1952.417 1952.500
## 1953 1953.000 1953.083 1953.167 1953.250 1953.333 1953.417 1953.500
## 1954 1954.000 1954.083 1954.167 1954.250 1954.333 1954.417 1954.500
## 1955 1955.000 1955.083 1955.167 1955.250 1955.333 1955.417 1955.500
## 1956 1956.000 1956.083 1956.167 1956.250 1956.333 1956.417 1956.500
## 1957 1957.000 1957.083 1957.167 1957.250 1957.333 1957.417 1957.500
## 1958 1958.000 1958.083 1958.167 1958.250 1958.333 1958.417 1958.500
## 1959 1959.000 1959.083 1959.167 1959.250 1959.333 1959.417 1959.500
## 1960 1960.000 1960.083 1960.167 1960.250 1960.333 1960.417 1960.500
##           Aug      Sep      Oct      Nov      Dec
## 1949 1949.583 1949.667 1949.750 1949.833 1949.917
## 1950 1950.583 1950.667 1950.750 1950.833 1950.917
## 1951 1951.583 1951.667 1951.750 1951.833 1951.917
## 1952 1952.583 1952.667 1952.750 1952.833 1952.917
## 1953 1953.583 1953.667 1953.750 1953.833 1953.917
## 1954 1954.583 1954.667 1954.750 1954.833 1954.917
## 1955 1955.583 1955.667 1955.750 1955.833 1955.917
## 1956 1956.583 1956.667 1956.750 1956.833 1956.917
## 1957 1957.583 1957.667 1957.750 1957.833 1957.917
## 1958 1958.583 1958.667 1958.750 1958.833 1958.917
## 1959 1959.583 1959.667 1959.750 1959.833 1959.917
## 1960 1960.583 1960.667 1960.750 1960.833 1960.917
qplot(time(AirPassengers), AirPassengers, geom = "line")
## Don't know how to automatically pick scale for object of type ts. Defaulting to continuous.
## Don't know how to automatically pick scale for object of type ts. Defaulting to continuous.

Esta solução só vale, contudo, para casos univariados, isto é, quando há apenas uma variável a ser plotada. No caso de múltiplas séries de tempo é preciso transformar os dados num data.frame e depois transformá-los em longitudinais. Usando funções base do R, a operação é bastante simples. Note que aqui se usa o ts.plot ao invés de plot.ts.

ts.plot(EuStockMarkets, col = rainbow(4))

A solução sugerida de agregar as séries num data.frame seria algo como:

# data.frame em que a primeria coluna marca a data (tempo)
# as outras colunas são as séries de tempo
dados <- data.frame(tempo = time(EuStockMarkets),
                    DAX = EuStockMarkets[, 1],
                    SMI = EuStockMarkets[, 2],
                    CAC = EuStockMarkets[, 3],
                    FTSE = EuStockMarkets[, 4])

# carrega pacote para manipulação de dados
library(tidyr)
dados_long <- dados %>% gather(variavel, valor, -tempo)

ggplot(data = dados_long, aes(x = tempo, y = valor, group = variavel)) +
  geom_line(aes(colour = variavel))

A primeira parte do código cria uma coluna com as datas usando a função time() e depois transforma cada uma das séries individuais numa nova coluna do data.frame. Depois, a função spread() transforma os dados em longitudinais, isto é, ao invés de termos cinco colunas, a primeira com as datas e as outras com as obervações de cada uma das variáveis, temos agora três colunas, a primeira ainda com as datas, mas agora a segunda com o nome da variável e a terceira com o valor desta variável. Isto é, cada valor é identificado com uma “data-variável”.

Table 1: Dados cross-section
tempo DAX SMI CAC FTSE
1991.496 1628.75 1678.1 1772.8 2443.6
1991.500 1613.63 1688.5 1750.5 2460.2
1991.504 1606.51 1678.6 1718.0 2448.2
1991.508 1621.04 1684.1 1708.1 2470.4
1991.512 1618.16 1686.6 1723.1 2484.7
1991.515 1610.61 1671.6 1714.3 2466.8
1991.519 1630.75 1682.9 1734.5 2487.9
1991.523 1640.17 1703.6 1757.4 2508.4
1991.527 1635.47 1697.5 1754.0 2510.5
1991.531 1645.89 1716.3 1754.3 2497.4
Table 2: Dados longitudinais
tempo variavel valor
1991.496 DAX 1628.75
1991.500 DAX 1613.63
1991.504 DAX 1606.51
1991.508 DAX 1621.04
1991.512 DAX 1618.16
1991.515 DAX 1610.61
1991.519 DAX 1630.75
1991.523 DAX 1640.17
1991.527 DAX 1635.47
1991.531 DAX 1645.89

ggplot e autoplot

library(forecast)
autoplot(AirPassengers)

Pode-se tratar o autoplot analogamente ao ggplot. No exemplo abaixo adiciono título e nomes para os eixos usando labs, troco a escala do eixos, adiciono um tema e troco a fonte do gráfico.

autoplot(EuStockMarkets) +
  labs(x = "", y = "", title = "Índices de Bolsas Europeias 1991-1998") +
  scale_y_continuous(breaks = seq(from = 2000, to = 8000, by = 2000),
                     labels = c("2,000", "4,000", "6,000", "8,000")) +
  scale_x_continuous(breaks = seq(from = 1992, 1999, 1)) +
  theme_minimal() +
  theme(
    legend.title = element_blank(),
    text = element_text(family = "", colour = "gray20")
    )

Outros tipo de gráficos (ggplot2)

Fundamentos: