Algumas vezes inserir imagens pode enriquecer um gráfico e atrair maior atenção. No R essa personalização da visualização de dados é relativamente simples usando o ggplot2 e suas extensões, conforme demonstramos nesse tutorial com exemplos inserindo imagens em pontos de observações.
Pacotes
Os pacotes utilizados neste exercício estão descritos a seguir. Você pode instalar os mesmos a partir do CRAN.
library(magrittr) # CRAN v2.0.1 library(purrr) # CRAN v0.3.4 library(glue) # CRAN v1.4.2 library(OECD) # CRAN v0.2.4 library(dplyr) # CRAN v1.0.7 library(lubridate) # CRAN v1.7.10 library(ggplot2) # CRAN v3.3.5 library(forcats) # CRAN v0.5.1 library(ggtext) # CRAN v0.1.1
Dados
Primeiro vamos coletar alguns dados e imagens de exemplo para construir uma visualização, objetivo é criar um gráfico da taxa de inflação de alguns países selecionados.
Os dados estão disponíveis na base da OECD e as imagens são provenientes do site flaticon.com e disponibilizados em nosso site. Importante: o script abaixo cria uma pasta temporária em seu computador e salva os arquivos de imagens (PNG) que utilizaremos neste exercício. Não execute o script se não deseja que isso seja feito.
# Link para imagens de bandeiras/país (Créditos: https://www.flaticon.com/) url_imgs <- "https://analisemacro.com.br/wp-content/uploads/2021/09/" # Nomes de arquivos PNG country_names <- c( "BRA", "CHN", "EU27_2020", "IND", "MEX", "RUS", "SAU", "TUR", "USA", "ZAF" ) # Criar pasta temporária temp_folder <- tempdir() # Baixar PNGs purrr::walk2( .x = url_imgs, .y = country_names, ~download.file( url = glue::glue("{.x}{.y}.png"), destfile = glue::glue("{temp_folder}/{.y}.png"), mode = "wb" ) ) # Coletar e tratar dados de inflação para países selecionados df_inflation <- OECD::get_dataset( dataset = "MEI", filter = "MEX+TUR+USA+BRA+CHN+IND+RUS+SAU+ZAF.CPALTT01.GY.M", start_time = 2021 ) %>% dplyr::select( "date" = `obsTime`, "country" = `LOCATION`, "value" = `obsValue` ) %>% dplyr::mutate( # Caminho do arquivo PNG path_to_imgs = glue::glue("{temp_folder}/{country}.png"), # Tag de imagem para ser usada no ggtext country_imgs = glue::glue("<img src='{path_to_imgs}' width='30'/>"), date = lubridate::ym(date), fill_col = dplyr::if_else(country == "BRA", "#b22200", "#282f6b") ) %>% dplyr::filter(date == lubridate::as_date("2021-07-01")) df_inflation ## # A tibble: 10 x 6 ## date country value path_to_imgs country_imgs fill_col ## <date> <chr> <dbl> <glue> <glue> <chr> ## 1 2021-07-01 MEX 5.81 "C:\\Users\\ferna\~ "<img src='C:\\User~ #282f6b ## 2 2021-07-01 TUR 19.0 "C:\\Users\\ferna\~ "<img src='C:\\User~ #282f6b ## 3 2021-07-01 USA 5.37 "C:\\Users\\ferna\~ "<img src='C:\\User~ #282f6b ## 4 2021-07-01 BRA 8.99 "C:\\Users\\ferna\~ "<img src='C:\\User~ #b22200 ## 5 2021-07-01 CHN 1 "C:\\Users\\ferna\~ "<img src='C:\\User~ #282f6b ## 6 2021-07-01 IND 5.26 "C:\\Users\\ferna\~ "<img src='C:\\User~ #282f6b ## 7 2021-07-01 RUS 6.47 "C:\\Users\\ferna\~ "<img src='C:\\User~ #282f6b ## 8 2021-07-01 ZAF 4.65 "C:\\Users\\ferna\~ "<img src='C:\\User~ #282f6b ## 9 2021-07-01 SAU 0.433 "C:\\Users\\ferna\~ "<img src='C:\\User~ #282f6b ## 10 2021-07-01 EU27_2020 2.5 "C:\\Users\\ferna\~ "<img src='C:\\User~ #282f6b
Criamos duas colunas importantes: a primeira (path_to_imgs) indica o caminho para o arquivo PNG salvo no computador e a segunda (country_imgs) é uma tag HTML para ser usada com o pacote ggtext, que interpreta o código lendo a imagem para ser renderizada no gráfico.
Um gráfico simples
Com os dados pronto podemos gerar uma simples visualização com o ggplot2, conforme abaixo:
# Gráfico simples plot_inflation <- df_inflation %>% ggplot2::ggplot( ggplot2::aes( x = forcats::fct_reorder(country, value, .desc = TRUE), y = value, fill = fill_col, color = fill_col, label = format(round(value, 2), nsmall = 2, decimal.mark = ","), width = 0.6 ) ) + ggplot2::geom_col() + ggplot2::geom_text(vjust = -0.5, fontface = "bold", size = 4.5) + ggplot2::geom_hline(yintercept = 0, color = "black", size = 1) + ggplot2::scale_color_identity(aesthetics = c("fill", "color")) + ggplot2::scale_y_continuous(breaks = c(0, 5, 10, 15, 20), limits = c(0, 20)) + ggplot2::theme_minimal() + ggplot2::labs( title = "**Inflação**", subtitle = glue::glue("Países selecionados, {format(max(df_inflation$date), '%B/%Y')}"), y = "% a/a", x = NULL, caption = "<br>**Dados:** OECD | **Gráfico:** analisemacro.com.br" ) + ggplot2::theme( panel.grid.minor = ggplot2::element_blank(), plot.title = ggtext::element_markdown(size = 20), plot.subtitle = ggplot2::element_text(size = 16), plot.caption = ggtext::element_markdown(size = 12), axis.text = ggplot2::element_text(size = 14, face = "bold"), axis.title.y = ggplot2::element_text(size = 14, face = "bold") ) plot_inflation
Gráfico com imagens: ggplot2 + ggtext
Vamos supor que queiramos enriquecer a visualização anterior inserindo imagens das bandeiras dos países no topo de cada coluna. Isso pode ser feito facilmente com o geom_richtext que, como o próprio nome diz, é muito útil para melhorar renderização e formatação de textos em gráficos do ggplot2.
Dessa forma, basta criar uma tag HTML img indicando a fonte do arquivo PNG e uma largura, conforme a coluna country_imgs do nosso objeto de dados, para incorporar uma imagem em vez de apenas formatar texto.
# Gráfico com imagens plot_inflation + ggtext::geom_richtext( ggplot2::aes(x = country, y = value, label = country_imgs), size = 1, fill = NA, label.color = NA )
Também podemos inserir as imagens no eixo X com o código abaixo, e observe que estamos replicando praticamente o mesmo código, mas mudando a estética principal aes() para ter x = country_imgs e o elemento do theme para axis.text.x = ggtext::element_markdown().
# Gráfico com imagens no eixo df_inflation %>% ggplot2::ggplot( ggplot2::aes( x = forcats::fct_reorder(country_imgs, value, .desc = TRUE), y = value, fill = fill_col, color = fill_col, label = format(round(value, 2), nsmall = 2, decimal.mark = ","), width = 0.6 ) ) + ggplot2::geom_col() + ggplot2::geom_text(vjust = -0.5, fontface = "bold", size = 4.5) + ggplot2::geom_hline(yintercept = 0, color = "black", size = 1) + ggplot2::scale_color_identity(aesthetics = c("fill", "color")) + ggplot2::scale_y_continuous(breaks = c(0, 5, 10, 15, 20), limits = c(0, 20)) + ggplot2::theme_minimal() + ggplot2::labs( title = "**Inflação**", subtitle = glue::glue("Países selecionados, {format(max(df_inflation$date), '%B/%Y')}"), y = "% a/a", x = NULL, caption = "<br>**Dados:** OECD | **Gráfico:** analisemacro.com.br" ) + ggplot2::theme( panel.grid.minor = ggplot2::element_blank(), plot.title = ggtext::element_markdown(size = 20), plot.subtitle = ggplot2::element_text(size = 16), plot.caption = ggtext::element_markdown(size = 12), axis.text = ggplot2::element_text(size = 14, face = "bold"), axis.text.x = ggtext::element_markdown(margin = ggplot2::margin(t = -5, unit = "pt")), axis.title.y = ggplot2::element_text(size = 14, face = "bold") )
Espero que esses exemplos tenham sido úteis para você!
________________________
(*) Para entender mais sobre a linguagem R e suas ferramentas, confira nosso Curso de Introdução ao R para análise de dados.