Exibindo observações como imagens no ggplot2

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.

Compartilhe esse artigo

Facebook
Twitter
LinkedIn
WhatsApp
Telegram
Email
Print

Comente o que achou desse artigo

Outros artigos relacionados

O que são SLMs?

Assim como os LLMs, os Small Language Models (SLMs) são Modelos de Linguagem baseados em IA em versões mais compactas, projetados para funcionar com menos recursos computacionais, menor latência e maior privacidade. Neste exercício mostramos como usar estes modelos usando API's ou localmente através do Python.

Boletim AM

Receba diretamente em seu e-mail gratuitamente nossas promoções especiais e conteúdos exclusivos sobre Análise de Dados!

Boletim AM

Receba diretamente em seu e-mail gratuitamente nossas promoções especiais e conteúdos exclusivos sobre Análise de Dados!

como podemos ajudar?

Preencha os seus dados abaixo e fale conosco no WhatsApp

Boletim AM

Preencha o formulário abaixo para receber nossos boletins semanais diretamente em seu e-mail.