Fundamentos: 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. Estes gráficos revelam a evolução de uma variável ao longo do tempo.
data-visualization
ggplot2
tutorial-R
Author

Vinicius Oike

Published

August 22, 2023

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. Estes gráficos revelam a evolução de uma variável ao longo do tempo. O ggplot oferece alguma variedade de funções para este fim, mas a mais comum é a 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.

Neste post vamos aprender a montar gráficos de linha usando o ggplot2 no R. Primeiro vamos fazer um exemplo simples para enxergar a dinâmica da taxa de poupança nos EUA. Depois, vamos entender como customizar o gráfico.

Além disso, vamos importar séries do Banco Central para fazer alguns exemplos aplicados usando o pacote GetBCBData.

R

Antes de iniciar precisamos carregar o pacote ggplot2, que traz as funções necessárias para montar os gráficos. Adicionalmente, vamos carregar o pacote GetBCBData, que utiliza a API do Sistema Gerador de Séries Temporais (SGS) do Banco Central do Brasil para baixar séries de tempo econômicas no R

Caso os pacotes não estejam instalados é preciso executar primeiro o código abaixo.

# Instala os pacotes necessários
install.packages(c("ggplot2", "GetBCBData"))

Para carregar os pactoes utilizamos a função library.

# Carrega o pacote ggplot2
library(ggplot2)
# Carrega o pacote GetBCBData
library(GetBCBData)

Além de servir como um repositório de funções, alguns pactoes também trazem bases de dados consigo. Neste exemplo vamos utilizar a base "economics" do pacote ggplot2.

data("economics")

Para consultar as bases de dados disponíveis basta utilizar o comando data() sem nenhum argumento como no código abaixo

data()

ggplot2

O pacote ggplot2 segue uma sintaxe bastante consistente, que permite “somar” elementos visuais sobre um mesmo gráfico. Isto permite que se crie uma infinidade de gráficos complexos a partir de elementos simples. Os elementos visuais são todos chamados por funções geom_*. Neste primeiro exemplo vamos focar na função geom_line() que desenha linhas. Estes elementos são todos somados de maneira intuitiva usando o sinal de soma +.

Essencialmente, temos os seguintes elementos principais:

  1. Dados - nossa tabela de dados.
  2. Função aes() - que transforma os dados em objetos visuais.
  3. Objeto geométrico (geom) - que escolhe qual o formato destes objetos visuais.

Estes elementos são combinados numa sintaxe recorrente. A função ggplot tipicamente tem apenas dois elementos: data e aes. O argumento data indica o nome da base de dados. Já a função aes é a que indica como transformar os dados (as colunas da base de dados) em elementos visuais. Nos casos mais simples, esta função serve para indicar qual é o nome da variável x e qual é o nome da variável y.

Adicionamos uma função geom nesta chamada inicial como no exemplo abaixo.

ggplot(data = dados, aes(x = varivel_x, y = variavel_y)) +
  geom_line()

Gráfico de linha

Para construir um gráfico de linha precisamos, em geral, de apenas dois arguementos: um argumento x que é o nome da variável no eixo-x (comumemente, o tempo) e um argumento y que é o nome da variável no eixo-y (comumemente, a variável numérica).

Vamos utilizar a base economics que é carregada conjuntamente com o pacote ggplot2. Esta base traz a evolução de algumas variáveis econômicas ao longo do tempo.

# Carrega a base de dados (caso ainda não tenha feito)
data("economics")
# Visualiza as primeiras linhas da base de dados
head(economics)
# A tibble: 6 × 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

Note que a primeira coluna à esquerda (date) traz as datas. A coluna psavert é a taxa de poupança individual, mensurada em proporção à renda disponível. Podemos visualizar como se altera a taxa de poupança ao longo do tempo.

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

Vamos quebrar o código acima em detalhes. Primeiro, usamos a função ggplot() para declarar que queremos fazer um gráfico. Colocamos os argumentos data e aes dentro desta função. O argumento data deve ser o nome da nossa base de dados: neste caso, data = economics.

O argumento aes é o que transforma as variáveis (as colunas da base de dados) em elementos visuais. Neste caso ele vai transformar o tempo e a taxa de poupança em algum elemento visual. Escolhemos aes(x = date, y = psavert).

Especificamos qual deve ser o elemento visual somando a função geom_line() no código inicial. Esta função indica que queremos um gráfico de linhas.

Unindo todas estes elementos temos um código enxuto que plota o gráfico. Vemos que a taxa de poupança nos EUA apresenta uma tendência de queda a partir da segunda metade dos anos 1970 que é revertida somente após a primeira metade dos anos 2000.

ggplot(
  # Especifica o nome da base de dados
  data = economics,
  # Indica como devem ser mapeadas as variáveis nos eixos x e y
  aes(x = date, y = psavert)) +
  # Especifica que queremos um gráfico de linha
  geom_line()

Opções estéticas

Podemos customizar um gráfico de ggplot modificando os seus elementos estéticos. Um elemento estético pode assumir dois tipos de valor: constante ou variável. Um valor constante é um número ou texto, enquanto uma variável é uma coluna da nossa base de dados.

Há quatro opções estéticas básicas para gráficos de linha: color, alpha, linewidth e linetype.

  • color - Define a cor da linha
  • alpha - Define o nível de transparência da linha
  • linewidth - Define a espessura da linha
  • linetype - Define o tracejado da linha

Cores

Utilizamos o argumento color dentro da função geom_line para variar a cor da linha no gráfico. Pode-se escolher a cor da linha tanto por nome como por código hexadecimal. Por padrão, a função geom_line utiliza color = "black". No exemplo abaixo utilizo um tom de azul chamado "steelblue". Uma lista completa de cores (por nome) está disponível aqui.

# Gráfico de linha
ggplot(data = economics, aes(x = date, y = psavert)) + 
  # Altera a cor da linha
  geom_line(color = "steelblue")

Também é possível chamar as cores via código hexadecimal como no exemplo abaixo.

# Gráfico de linha
ggplot(data = economics, aes(x = date, y = psavert)) +
  # Altera a cor da linha
  geom_line(color = "#e76f51")

Alpha

O argumento alpha controla o nível de transparência da cor e varia de 0 a 1, em que alpha = 0 é perfeitamente transparente e alpha = 1 é nada transparente. Por padrão, a função geom_line define que alpha = 1. Na prática, são raros os casos em que vale alterar este argumento. No exemplo abaixo definimos alpha = 0.5.

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

Espessura da linha

O argumento linewidth controla a espessura da linha. No exemplo abaixo defino linewidth = 1 dentro da função geom_line(). Na prática, não recomendo escolher um valor de linewidth acima de 1 pois a linha se torna muito espessa.

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

O gráfico abaixo compara alguns tamanhos diferentes de espessura de linha. Note que é possível especificar valores não-inteiros como 0,5. Para evitar de repetir o mesmo código várias vezes, guardo a chamada inicial do ggplot em um objeto chamado p (de plot).

p <- ggplot(data = economics, aes(x = date, y = psavert))

# Espessura = 0.5
p + geom_line(linewidth = 0.5)
# Espessura = 1
p + geom_line(linewidth = 1)
# Espessura = 2
p + geom_line(linewith = 2)
# Espessura = 5
p + geom_line(linewidth = 5)

Tracejado da linha

O argumento linetype controla o tracejado da linha. Por padrão, a função geom_line() utiliza linetype = 1, mas podemos escolher valores distintos. No exemplo abaixo usamos linetype = 2.

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

Abaixo pode-se ver a diferença entre cada uma delas.

Combinando elementos

Como foi aludido no início do post, parte da mágica do ggplot é de poder somar elementos ao mesmo gráfico. Isto permite uma grande flexibilidade na hora de montar nossas visualizações. Uma combinação bastante efetiva é juntar um gráfico de linha com um gráfico de pontos.

Primeiro, vamos importar a série do consumo de energia elétrica residencial no Brasil. Podemos importar séries de tempo do site do Banco Central do Brasil usando a função gbcbd_get_series do pacote GetBCBData.

Para importar uma série de tempo precisamos informar apenas: (1) o código da série pelo argumento id; e (2) a data de início da extração pelo argumento first.date (no formato YYYY-MM-DD).

# Import a série de consumo de energia elétrica residencial
consumo <- gbcbd_get_series(id = 1403, first.date = as.Date("2014-01-01"))

O gráfico abaixo combina um geom_line() com um geom_point() para representar tanto os pontos de observação como a linha que une os pontos.

ggplot(data = consumo, aes(x = ref.date, y = value)) +
  # Linha da série
  geom_line() +
  # Pontos sinalizando as observações
  geom_point()

Mapeando elementos estéticos

Cores

Como de costume, as características estéticas do gráfico podem refletir grupos de variáveis. No caso de gráficos de linha é comum querer representar séries de tempo distintas com cores diferentes.

Vamos importar três séries de tempo: o consumo de energia elétrica comercial (1402), residencial (1403) e industrial (1404). Todas as séries são mensais e são importadas a partir de janeiro de 2014.

# Importa as séries mensais do consumo de energia elétrica
series <- gbcbd_get_series(
  id = c(1402, 1403, 1404),
  first.date = as.Date("2014-01-01")
  )

Os dados são automaticamente formatados no padrão longitudinal, em que cada linha representa uma observação no tempo de uma série em particular. Este é o formato ideal para trabalhar com visualizações em ggplot, onde os dados estão “empilhados”.

A coluna ref.date indica a data, a coluna series.name identifica o id da série e a coluna value representa o valor desta observação.

ref.date value id.num series.name
2014-01-01 7745 1402 id = 1402
2014-01-01 11798 1403 id = 1403
2014-01-01 14537 1404 id = 1404
2014-02-01 8204 1402 id = 1402
2014-02-01 11879 1403 id = 1403
2014-02-01 15107 1404 id = 1404

Vamos mapear a coluna series.name nas cores das linhas. Para especificar isto utilizamos a função aes, que serve para transformar dados em elementos visuais. Da mesma forma como mapeamos a coluna ref.date e value numa linha, agora mapeamos series.name nas cores do gráfico.

ggplot(data = series, aes(x = ref.date, y = value)) +
  geom_line(
    # Indica que a variável series.name deve ser mapeada nas cores das linhas
    aes(color = series.name))

As escolhas de cores padrão nem sempre são satisfatórias. Para modificar as cores utilizamos a função scale_color_manual() que também nos dá controle sobre a legenda do gráfico.

ggplot(data = series, aes(x = ref.date, y = value)) +
  geom_line(aes(color = series.name)) +
  # Controla as cores e a legenda
  scale_color_manual(
    # Título da legenda (opcional)
    name = "Consumo de energia",
    # Nome das séries (opcional)
    labels = c("Comercial", "Residencial", "Industrial"),
    # Cores das linhas
    values = c("#264653", "#e9c46a", "#e76f51"),
  )

Vale notar que existem vários pacotes e funções com cores pré-definidas que simplificam o processo manual de escolher as cores. O exemplo mais simples é o scale_color_brewer() que utiliza as paletas de cores do Color Brewer.

ggplot(data = series, aes(x = ref.date, y = value)) +
  geom_line(aes(color = series.name)) +
  # Controla as cores e a legenda
  scale_color_brewer(
    # Título da legenda (opcional)
    name = "Consumo de energia",
    # Nome das séries (opcional)
    labels = c("Comercial", "Residencial", "Industrial"),
    # Tipo ("qual" - qualitativo, "div" - divergente ou "seq" - sequencial)
    type = "qual",
    # Escolha da paleta
    palette = 6
  )

Por padrão, a legenda das cores é colocada no lado direito do gráfico. Para modificar a sua posição usamos a função theme().

ggplot(data = series, aes(x = ref.date, y = value)) +
  geom_line(aes(color = series.name)) +
  scale_color_brewer(
    name = "Consumo de energia",
    labels = c("Comercial", "Residencial", "Industrial"),
    type = "qual",
    palette = 6) +
  theme(
    # Define a posição da legenda (top, bottom, right ou left)
    legend.position = "bottom"
  )

Tipo de linha

Da mesma forma que modificamos a cor das linhas, podemos variar outros aspectos estéticos como, por exemplo, o tracejado da linha de cada série. Este tipo de modificação pode ser útil no caso de uma publicação que vai ser visualizada ou impressa em escala de cinza.

ggplot(data = series, aes(x = ref.date, y = value)) +
  geom_line(
    # Cada série é desenhada com um tracejado diferente
    aes(linetype = series.name)
    ) +
  # Controla a legenda das séries
  scale_linetype_discrete(
    # Título da legenda (opcional)
    name = "Consumo de energia",
    # Nome das séries (opcional)
    labels = c("Comercial", "Residencial", "Industrial")
  )

Por fim, podemos modificar elementos estéticos de dois geoms no mesmo gráfico. No exemplo abaixo tanto o tracejado da linha como o formato do ponto variam segundo a série.

ggplot(data = series, aes(x = ref.date, y = value)) +
  geom_line(aes(linetype = series.name)) +
  geom_point(aes(shape = series.name)) +
  # Controla a legenda das séries
  scale_linetype_discrete(
    # Título da legenda (opcional)
    name = "Consumo de energia",
    # Nome das séries (opcional)
    labels = c("Comercial", "Residencial", "Industrial")
  ) +
  scale_shape_discrete(
    # Título da legenda (opcional)
    name = "Consumo de energia",
    # Nome das séries (opcional)
    labels = c("Comercial", "Residencial", "Industrial")
  )

Renomeando os eixos do gráfico

É muito importante que um gráfico seja o mais auto-explicativo possível. Para isso precisamos inserir informações relevantes como título, subtítulo e fonte.

A função labs() permite facilmente renomear os eixos do gráfico. Os argumentos principais são os abaixo.

  • title - título do gráfico
  • subtitle - subtítulo do gráfico
  • x - título do eixo-x (horizontal)
  • y - título do eixo-y (vertical)
  • caption - legenda abaixo do gráfico (em geral, a fonte)

No caso de gráficos de linha é muito comum omitir o nome do eixo-x, pois ele geralmente representa o tempo. Para omitir o nome de qualquer eixo basta defini-lo como NULL.

Novamente, utilizamos o sinal de soma para adicionar estes elementos ao gráfico.

ggplot(data = consumo, aes(x = ref.date, y = value)) +
  # Linha da série
  geom_line() +
  # Define os elementos textuais do gráfico
  labs(
    title = "Aumento gradual na demanda por energia elétrica",
    subtitle = "Consumo residencial de energia elétrica no Brasil.",
    # Omite o título do eixo-x
    x = NULL,
    y = "GWh",
    caption = "Fonte: Eletrobras."
    )

Começando o gráfico do zero

Os gráficos de linha gerados pelo ggplot2 não começam do zero no eixo-y. Isto pode ser um problema e, visualmente, criar a ilusão de que há mais volatilidade nos dados do que realmente existe.

Há muitas formas de forçar o gráfico a iniciar no zero. Uma das mais efetivas é incluir uma linha horizontal no eixo (\(y = 0\)). Pode-se desenhar esta linha horizontal com a função geom_hline() (onde o “hline” sinaliza “horizontal line”, linha horizontal).

ggplot(data = consumo, aes(x = ref.date, y = value)) +
  # Linha horizontal y = 0
  geom_hline(yintercept = 0) +
  # Linha da série
  geom_line()

Outra forma de chegar no mesmo resultado é manipular o eixo-y para forçá-lo a iniciar no zero. No exemplo abaixo utilizamos a função scale_y_continuous(). Esta função controla todos os aspectos visuais da escala no eixo-y. O sufixo _continuous indica que a variável no eixo-y é contínua.

Para redefinir os limites do eixo-y variamos o argumento limits que aceita um par de valores. O primeiro valor é o limite inferior e o segundo valor é o limite superior. Por padrão ambos são definidos como NA.

ggplot(data = consumo, aes(x = ref.date, y = value)) +
  # Linha da série
  geom_line() +
  # Manipular o eixo-y para inicar no zero
  scale_y_continuous(limits = c(0, NA))

Séries de tempo em degraus

Algumas séries de tempo variam de maneira “descontínua” no tempo. É o caso, por exemplo, da taxa SELIC, que é periodicamente definida como uma meta a ser perseguida pelo Banco Central. Neste caso, faz sentido ressaltar isto fazendo um gráfico que varia em “degraus”.

A função geom_step() faz este tipo de gráfico e possui os mesmos argumentos que a função geom_line(). O gráfico abaixo mostra a variação da taxa SELIC (meta) nos últimos anos.

# Importa a série diária da SELIC (meta) anualizada
selic <- gbcbd_get_series(id = 1178, first.date = as.Date("2016-01-01"))

ggplot(data = selic, aes(x = ref.date, y = value)) +
  geom_step()

Resumo

Neste post aprendemos o básico da estrutura sintática do ggplot e conseguimos montar gráficos de linha sofisticados usando poucas linhas de código. Em qualquer gráfico temos três elementos básicos

  1. Dados - nossa tabela de dados.
  2. Função aes() - que transforma os dados em objetos visuais.
  3. Objeto geométrico (geom) - que escolhe qual o formato destes objetos visuais.

Alguns pontos de destaque:

  1. Utilize cores diferentes para séries distintas usando aes(color = ...).
  2. Combine elementos como linhas e pontos somando os “geoms”.
  3. Comece o gráfico no zero utilizando ou geom_hline(yintercept = 0) ou scale_y_continuous(limits=c(0,NA)).

Seguindo esta lógica e somando os objetos podemos criar belos gráficos.

# Importa as séries mensais do consumo de energia elétrica
series <- gbcbd_get_series(
  id = c(1402, 1403, 1404),
  first.date = as.Date("2019-01-01")
  )

ggplot(data = series, aes(x = ref.date, y = value)) +
  geom_hline(yintercept = 0) +
  geom_line(
    aes(color = series.name),
    linewidth = 1) +
  geom_point(
    aes(color = series.name),
    size = 2) +
  scale_color_manual(
    name = "Consumo de Energia",
    labels = c("Comercial", "Residencial", "Industrial"),
    values = c("#264653", "#e9c46a", "#e76f51")) +
  labs(
    title = "Recuperação do consumo de energia pós-pandemia",
    subtitle = "Consumo mensal de energia elétrica segundo a finalidade.",
    x = NULL,
    y = "(GWh)",
    caption = "Fonte: Eletrobras.") +
  theme(
    legend.position = "bottom"
  )