O heatmap é um gráfico muito útil para identificar padrões, principalmente quando temos muitas variáveis no gráfico. Essencialmente o heatmap necessita de 3 variáveis: uma variável resposta e duas outras variáveis para compor os eixos x e y. Não há restrição quanto ao tipo de variável, qualquer uma delas podem ser quantitativa ou qualitativa. Talvez esse seja o trunfo do heatmap, essa flexibilidade quanto a natureza das variáveis nos permite utilizá-lo em diversos momentos e substituir gráficos mais tradicionais quando eles não dão conta do recado.

Vamos trabalhar com os dados do Projeto TUME, especificamente com o TUME 0, plantado na Estação Experimental de Itatinga. O TUME é um projeto muito interessante e possui informações importantes sobre plantios de Eucalyptus no Brasil, vale a pena visitar o site e aproveitar o conteúdo disponível.

Vamos primeiro carregar os dados e fazer algumas alterações. Para auxiliar na ordem dos fatores no gráfico vamos adicionar um atributo na coluna Esp informando a ordem crescente das espécies em função da altura dominante. Em seguida, apenas por conveniência, converti a idade dos inventários de meses para anos.

if (!require("pacman")) install.packages("pacman")
pacman::p_load(readr, dplyr, ggplot2)
dados <- read_csv2(
  "https://github.com/italocegatta/italocegatta.github.io_source/raw/master/content/dados/tume0.csv"
)

# Cria um fator com o atributo para a variável Esp que informa a ordem crescente
# das espécies em função da altura dominante.
dados <- dados %>% 
  mutate(
    Esp = reorder(Esp, Hdom, function(x) max(x)),
    Idade = round(I_meses/12,1)
  )
dados
## # A tibble: 138 x 16
##    N_tume Esp   I_meses Parc_m2 DAPmed DAPsd  Hmed   Hsd  Hdom N_fuste
##     <dbl> <fct>   <dbl>   <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl>
##  1      0 Clon~      52   1426.   11.4   1.4  16.5   1.3  17.8    1789
##  2      0 Clon~      52   1426.   10.2   1.4  15.9   1.4  16.6    1662
##  3      0 Clon~      52   1426.   10.7   1.6  15     1.3  16.1    1824
##  4      0 E_be~      52   1426.    9     2.7   9.8   2.3  13      1494
##  5      0 E_bo~      52   1426.    9.1   4.3  10.8   3.4  15.3    1368
##  6      0 E_ca~      52   1426.    8.3   2.9   8.3   2.3  11.8    1557
##  7      0 E_ci~      52   1426.    8     3.5   8.3   2.8  12       954
##  8      0 E_cl~      52    929.    7.5   2.5   7     2     9.6    1367
##  9      0 E_de~      52   1426.   10.6   2.9  11.3   1.8  13.4    1087
## 10      0 E_du~      52   1426.    6.7   3.7   6.1   2.4  10.3     779
## # ... with 128 more rows, and 6 more variables: Sobr <dbl>, G <dbl>,
## #   V <dbl>, IMA <dbl>, B <dbl>, Idade <dbl>

Se fizermos a seguinte pergunta: qual gráfico podemos utilizar para mostrar o crescimento da altura dominantes dos materiais? Penso que a resposta rápida seria, um gráfico de linhas! Ok, vamos tentar, veja a Figura 1.

ggplot(dados, aes(Idade, Hdom, color = Esp)) +
  geom_line(size=1.5) +
  labs(
    x = "Idade (anos)", y = "Altura dominante (m)",
    color = "Materiais genéticos"
  ) +
  scale_color_viridis_d(direction = -1) +
  theme_bw(16) +
  guides(col = guide_legend(ncol = 1, reverse = TRUE))
Aumento da altura dominante utilizando gráficos de linhas.

Figura 1: Aumento da altura dominante utilizando gráficos de linhas.

Muito bem, o gráfico consegue mostrar a tendência e o padrão de crescimento. Mas se alguém perguntar sobre o Eucaluptus dunnii, capaz de demorarmos um tempo para encontrar a linha correspondente. Capaz ainda de não conseguirmos distinguir entre uma cor e outra. Essa é uma limitação do gráfico de linhas, quanto temos muitos fatores na legenda fica difícil a distinção entre eles. E quando se tem uma restrição de cor e o gráfico precisa estar em escala de cinza? Esquece! Há quem tente utilizar símbolos ou tipos de traços para distinguir os fatores, mesmo assim, não é uma tarefa fácil.

É neste momento que podemos nos aproveitar do heatmap. Agora a intensidade de cor indica a variável resposta (Figura 2). Veja que fica mais fácil acompanhar o crescimento de uma espécie em especial.

ggplot(dados, aes(factor(Idade), Esp, fill = Hdom)) +
  geom_tile(color = "grey90") +
  labs(
    x = "Idade (anos)", y = "Altura dominante (m)",
    fill = "Materiais genéticos"
  ) +
  scale_fill_viridis_c(direction = -1) +
  theme_bw(16) +
  guides(col = guide_legend(reverse = TRUE))
Aumento da altura dominante utilizando heatmap com escala de cor contínua.

Figura 2: Aumento da altura dominante utilizando heatmap com escala de cor contínua.

Se for do interesse controlar a escala de cor em intervalos e classes, a alteração é simples (Figura 3). Se reduzirmos as classes de cor, perdemos resolução na escala da variável resposta. Dependendo do objetivo do gráfico isso pode ser bom ou ruim. Neste caso, escolhi intervalos de 2 metros, pois achei mais adequado.

ggplot(dados, aes(factor(Idade), Esp, fill = cut(Hdom, breaks = seq(0, 40, 2)))) +
  geom_tile(color = "grey90") +
  labs(
    x = "Idade (anos)", y = "Materiais genéticos",
    fill = "Altura dominante (m)"
  ) +
  scale_fill_viridis_d(direction = -1) +
  theme_bw(16) +
  guides(col = guide_legend(reverse = TRUE))
Aumento da altura dominante utilizando heatmap com escala de cor discreta.

Figura 3: Aumento da altura dominante utilizando heatmap com escala de cor discreta.

Se quisermos deixar explícito o valor da variável resposta podemos indicá-la no gráfico, como na Figura 4. Eu particularmente acho que fica muito poluído, mas em alguns casos pode ser interessante.

ggplot(dados, aes(factor(Idade), Esp, fill = cut(Hdom, breaks = seq(0, 40, 2)))) +
  geom_tile(color = "grey90") +
  geom_text(aes(label = Hdom), color = "white", fontface = "bold") +
  labs(
    x = "Idade (anos)", y = "Materiais genéticos",
    fill = "Altura dominante (m)"
  ) +
  scale_fill_viridis_d(direction = -1, end = 0.92) +
  theme_bw(16) +
  guides(col = guide_legend(reverse = TRUE))
Aumento da altura dominante utilizando heatmap com escala de cor discreta e informação do valor no grid.

Figura 4: Aumento da altura dominante utilizando heatmap com escala de cor discreta e informação do valor no grid.

Note que o eixo x é uma variável temporal, entretanto o gráfico não dá a escala entre os anos. Um observador desatento pode achar que as medições ocorreram em intervalos regulares, mas isso não é verdade. Essa é uma desvantagem do heatmap. Quando as variáveis dos eixos são numéricas e representam uma escala comparativa, este atributo fica comprometido.

Caso tenha alguma dúvida ou sugestão sobre o post, fique à vontade para fazer um comentário ou me contatar por E-mail.

sessioninfo::session_info(c("readr", "dplyr", "ggplot2"))
## - Session info ----------------------------------------------------------
##  setting  value                       
##  version  R version 3.5.3 (2019-03-11)
##  os       Windows 10 x64              
##  system   x86_64, mingw32             
##  ui       RTerm                       
##  language (EN)                        
##  collate  Portuguese_Brazil.1252      
##  ctype    Portuguese_Brazil.1252      
##  tz       America/Sao_Paulo           
##  date     2019-08-25                  
## 
## - Packages --------------------------------------------------------------
##  package      * version  date       lib source        
##  assertthat     0.2.1    2019-03-21 [1] CRAN (R 3.5.3)
##  backports      1.1.4    2019-04-10 [1] CRAN (R 3.5.3)
##  BH             1.69.0-1 2019-01-07 [1] CRAN (R 3.5.2)
##  cli            1.1.0    2019-03-19 [1] CRAN (R 3.5.3)
##  clipr          0.7.0    2019-07-23 [1] CRAN (R 3.5.3)
##  colorspace     1.4-1    2019-03-18 [1] CRAN (R 3.5.3)
##  crayon         1.3.4    2017-09-16 [1] CRAN (R 3.5.1)
##  digest         0.6.20   2019-07-04 [1] CRAN (R 3.5.3)
##  dplyr        * 0.8.3    2019-07-04 [1] CRAN (R 3.5.3)
##  ellipsis       0.2.0.1  2019-07-02 [1] CRAN (R 3.5.3)
##  fansi          0.4.0    2018-10-05 [1] CRAN (R 3.5.1)
##  ggplot2      * 3.2.1    2019-08-10 [1] CRAN (R 3.5.3)
##  glue           1.3.1    2019-03-12 [1] CRAN (R 3.5.3)
##  gtable         0.3.0    2019-03-25 [1] CRAN (R 3.5.3)
##  hms            0.5.0    2019-07-09 [1] CRAN (R 3.5.3)
##  labeling       0.3      2014-08-23 [1] CRAN (R 3.5.0)
##  lattice        0.20-38  2018-11-04 [2] CRAN (R 3.5.3)
##  lazyeval       0.2.2    2019-03-15 [1] CRAN (R 3.5.3)
##  magrittr       1.5      2014-11-22 [1] CRAN (R 3.5.1)
##  MASS           7.3-51.1 2018-11-01 [2] CRAN (R 3.5.3)
##  Matrix         1.2-17   2019-03-22 [1] CRAN (R 3.5.3)
##  mgcv           1.8-28   2019-03-21 [1] CRAN (R 3.5.3)
##  munsell        0.5.0    2018-06-12 [1] CRAN (R 3.5.1)
##  nlme           3.1-137  2018-04-07 [2] CRAN (R 3.5.3)
##  pillar         1.4.2    2019-06-29 [1] CRAN (R 3.5.3)
##  pkgconfig      2.0.2    2018-08-16 [1] CRAN (R 3.5.1)
##  plogr          0.2.0    2018-03-25 [1] CRAN (R 3.5.1)
##  plyr           1.8.4    2016-06-08 [1] CRAN (R 3.5.1)
##  purrr          0.3.2    2019-03-15 [1] CRAN (R 3.5.3)
##  R6             2.4.0    2019-02-14 [1] CRAN (R 3.5.2)
##  RColorBrewer   1.1-2    2014-12-07 [1] CRAN (R 3.5.0)
##  Rcpp           1.0.2    2019-07-25 [1] CRAN (R 3.5.3)
##  readr        * 1.3.1    2018-12-21 [1] CRAN (R 3.5.2)
##  reshape2       1.4.3    2017-12-11 [1] CRAN (R 3.5.1)
##  rlang          0.4.0    2019-06-25 [1] CRAN (R 3.5.3)
##  scales         1.0.0    2018-08-09 [1] CRAN (R 3.5.1)
##  stringi        1.4.3    2019-03-12 [1] CRAN (R 3.5.3)
##  stringr        1.4.0    2019-02-10 [1] CRAN (R 3.5.2)
##  tibble         2.1.3    2019-06-06 [1] CRAN (R 3.5.3)
##  tidyselect     0.2.5    2018-10-11 [1] CRAN (R 3.5.1)
##  utf8           1.1.4    2018-05-24 [1] CRAN (R 3.5.1)
##  vctrs          0.2.0    2019-07-05 [1] CRAN (R 3.5.3)
##  viridisLite    0.3.0    2018-02-01 [1] CRAN (R 3.5.1)
##  withr          2.1.2    2018-03-15 [1] CRAN (R 3.5.1)
##  zeallot        0.1.0    2018-01-28 [1] CRAN (R 3.5.2)
## 
## [1] C:/Users/Italo/Documents/R/win-library/3.5
## [2] C:/Program Files/R/R-3.5.3/library