11.7 Gráfico do tempo de Santa Maria-RS em 2020

Para ilustrar a abordagem de construção de gráficos por camadas do {ggplot2} vamos visualizar a variação temperatura diária do ar para o ano corrente e compará-la com a climatologia e estatísticas baseadas em 58 anos de dados. Nós vamos explorar diferentes geometrias (linhas, pontos, intervalos)

Nós criamos um gráfico a partir da função ggplot(), especificando os dados de entrada.

ggplot(data = clima)

O resultado é um painel em branco. A construção de um gráfico com o {ggplot2} envolve a especificação atributos estéticos (eixos x e y), adição de elementos geométricos aos nossos dados, operações estatísticas, escalas, coordenadas e várias utras componentes.

Podemos adicionar geometrias usando o operador +, conforme mostrado abaixo. Para criar o gráfico da temperatura do ar (tar) de Santa Maria-RS, precisamos mapear as variáveis de interesse dos dados de entrada para o eixo y e x. Este mapeamento das variáveis nos exos é feito pela função aes() (de aesthetics, estética em inglês). Ela indica a relação entre os dados, a variável que será representada no eixo x, a que será representada no eixo y, a cor, o tamanho dos componentes geométricos etc. Os aspectos que podem ou devem ser mapeados depende do tipo de gráfico que você está construindo.

Nossa primeira camada de geometria será uma linha vertical unindo o valor mínimo até o máximo absoluto de tar (variáveis tar_min e tar_max) associado a cada dia do ano (dda). A variável dda é especificada no eixo x. Para inserir uma linha vertical a geom_linerange() requer os argumentos x, ymin e ymax.

ggplot( data = clima) +
  geom_linerange(
    mapping = aes(x = dda, ymin = tar_min, ymax = tar_max),
    color = "wheat2"
   # alpha = .1
  ) 

Além de identificar as variáveis de cada eixo nós adicionamos o argumento color para distinguir os intervalos variação entre os máximos e mínimos absolutos registrados.

Uma versatilidade do {ggplot2} é de podermos armazenar os gráficos em objetos. Então o gráfico básico acima pode ser armazenado numa váriavel. A estrutura do gráfico é uma lista com todas componentes necessárias para construção do gráfico.

graf_base <- 
  ggplot( data = clima) +
  #geom_point(size = 0.01, colour = "green") +
  geom_linerange(
    mapping = aes(x = dda, ymin = tar_min, ymax = tar_max),
    color = "wheat2"
   # alpha = .1
  ) +
   theme(#plot.background = element_blank(),
          panel.grid.minor.x = element_blank(),
          panel.grid.major.y = element_blank(),
          panel.border = element_blank(),
          panel.background = element_blank(),
          axis.ticks = element_blank(),
          #axis.text = element_blank(),  
          axis.title = element_blank()
  )

glimpse(graf_base, max.level = 1)

Na sequência vamos adicionar uma segunda camada com os dados que representam o intervalo de confiança de 95% da temperatura média diária para o período de 1952-2019.

ggp_sm <- graf_base + 
geom_linerange(
    mapping = aes(x = dda, ymin = tar_med_min, ymax = tar_med_max),
    color = "wheat4"
  )
ggp_sm

Agora vamos incorporar ao gráfico os dados de temperatura do ano atual e uma linha vertical (geom_vline) na borda esquerda do eixo y.

ggp_sm <- ggp_sm +
  geom_line(
    data = tempo,
    mapping = aes(x = dda, y = tar),
    # size = 1
  ) +
  geom_vline(xintercept = 0, color = "wheat4", linetype = 1, size = 1)
ggp_sm

Agora vamos ajustar a escala do eixo y ao intervalo de variação da dos extremos e definir 8 marcas para os labels.

int_var <- range(c(clima$tar_max, clima$tar_min))
int_var <- c(floor(int_var[1]), ceiling(int_var[2]))
int_var
ggp_sm <- ggp_sm +
  scale_y_continuous(
    limits = int_var,
    breaks = scales::pretty_breaks(n = 8),
    labels = scales::label_number(suffix = " °C", accuracy = 5)
  ) + 
  scale_x_continuous(expand = c(0, 0), 
                     breaks = marcas_x$metade, 
                     labels = marcas_x$labels,
                     )
ggp_sm

Podemos adicionar linhas de grade horizontais e verticais como referência. As linhas verticais serão adicionadas no último dia de cada mês. As horizontais serão espaçadas de 5°C.

ggp_sm <- ggp_sm + 
  geom_hline(
    yintercept = seq(int_var[1], int_var[2], by = 5), 
    color = "white", 
    linetype = 1
    ) + 
  geom_vline(
    xintercept = marcas_x$final, 
    color = "wheat4", 
    linetype = 3,
    size = 0.5
    ) 
ggp_sm

Neste ponto, vamos identificar os dias que em 2020 ultrapassaram os recordes históricos de temperatura.

ggp_sm <- ggp_sm + 
   geom_point(
     data = filter(recordes_atual, record_min == "S"),
     aes(x = dda, y = tar), color = "blue3") + 
   geom_point(
     data = filter(recordes_atual, record_max == "S"),
     aes(x = dda, y = tar), color = "firebrick3")
ggp_sm

Com todos dados plotados agora podemos incrementá-lo com texto apropriado. Primeiramente vamos adicionar um título e subtítulo.

ggp_sm <- ggp_sm +
  ggtitle("Tempo em Santa Maria, 2020") +
  theme(
    plot.title = element_text(
      face = "bold",
      hjust = .012,
      vjust = .8,
      colour = "#3C3C3C",
      size = 20
    )
  ) +
  annotate("text",
    x = 138,
    y = 36,
    label = "Temperatura",
    size = 4,
    fontface = "bold"
  ) 
ggp_sm

Nós podemos adicionar um parágrafo abaixo do subtítulo para dar uma pequena explanação dobre os dados. O texto será separado em 4 anotações.

texto <- "Os dados representam as médias diárias de temperatura. Os dados iniciam efetivamente em 1951. Dados para 2020 são disponíveis somente até Julho. A Temperatura média anual até este mês foi de 22°C, caracterizando 2020 como o 8° ano mais quente."

ggp_sm <- ggp_sm +
  annotate("text",
    x = 120,
    y = 32.5,
    label = str_wrap(texto, width = 70),
    size = 3,
    colour = "gray30",
    hjust = 0
  )
ggp_sm

Anotações que explicam os pontos representando os dias nos quais ocorreram recordes de temperatura máxima e mínima.

x_rec_tmin <- filter(recordes_atual, record_min == "S") %>% 
  pull(dda)
y_rec_tmin <- filter(recordes_atual, record_min == "S") %>% 
  pull(tar_min)

x_rec_tmax <- filter(recordes_atual, record_max == "S") %>% 
  pull(dda) %>% 
  extract(3)
y_rec_tmax <- filter(recordes_atual, record_max == "S") %>% 
  pull(tar_max) %>%
  extract(3)


ggp_sm <- ggp_sm +
  annotate("segment",
           x = x_rec_tmin - 2, xend = x_rec_tmin - 12,
           y = y_rec_tmin - 1, yend = y_rec_tmin - 3,
           color = "blue3"
           ) + 
  annotate("text", 
           x = x_rec_tmin - 12, 
           y = y_rec_tmin - 3 -0.5, 
           label = "Recorde de Tmin",
           size=2.9, 
           colour="blue3"
           ) +
    annotate("segment",
           x = x_rec_tmax + 2, xend = x_rec_tmax + 12,
           y = y_rec_tmax + 1, yend = y_rec_tmax + 2,
           color = "firebrick3"
           ) + 
  annotate("text", 
           x = x_rec_tmax + 13, 
           y = y_rec_tmax + 3, 
           label = "Recordes de Tmax",
           size = 2.9, 
           colour="firebrick3"
           )
ggp_sm
leg_dados <- data.frame(x = seq(53, 61), y = rnorm(9, mean = 12, 1))

ggp_sm +
  # limites extremos
  annotate("segment",
    x = marcas_x$final[2],
    xend = marcas_x$final[2],
    y = 9,
    yend = 15,
    colour = "wheat2",
    size = 3
  ) +
  # intervalo intermediário
  annotate("segment",
    x = marcas_x$final[2],
    xend = marcas_x$final[2],
    y = 10.5,
    yend = 13.5,
    colour = "wheat4",
    size = 3
  ) +
  geom_line(data = leg_dados, aes(x = x, y = y)) +
  # labels intermediários
  annotate("text",
    x = 36,
    y = 12,
    label = "TEMPERATURA 2020",
    size = 2,
    colour = "gray30"
  ) +
  annotate("text",
    x = 84,
    y = 12,
    label = "INTERVALO NORMAL",
    size = 2,
    colour = "gray30"
  ) +
  # labels extremos
  annotate("text",
    x = 70,
    y = 15,
    label = "MÁXIMO",
    size = 2,
    colour = "gray30"
  ) +
  annotate("text",
    x = 70,
    y = 9.5,
    label = "MÌNIMO",
    size = 2,
    colour = "gray30"
  ) +
  # segmentos do intervalo normal
  annotate("segment", 
           x = 63, 
           xend = 65, 
           y = 10.5,
           yend = 10.5,
           colour = "wheat4", 
           size=.5
           ) +
  annotate("segment", 
           x = 63, 
           xend = 65, 
           y = 13.5,
           yend = 13.5,
           colour = "wheat4", 
           size=.5
           ) +
  annotate("segment", 
           x = 65, 
           xend = 65, 
           y = 10.5,
           yend = 13.5,
           colour = "wheat4", 
           size=.5
           )