Visualização de Dados - Parte 2

Prof. Edneide Ramalho

Pacotes

library(tidyverse)
library(gtsummary)

Dados

Vamos usar os dados do Enem para fazer mais alguns exemplos: https://www.gov.br/inep/pt-br/acesso-a-informacao/dados-abertos/microdados/enem

Gráfico de densidade

Quando usar: alternativa mais suave ao histograma para variáveis contínuas. Excelente para comparar distribuições de grupos. Pergunta que responde: “Qual a forma da distribuição? Onde se concentram os valores?”

# Básico
ggplot(diamonds, aes(x = x)) +
  geom_density(fill = "#534AB7", alpha = 0.5) +
  theme_minimal()

# Comparando grupos — onde o density brilha
ggplot(diamonds, aes(x = x, fill = cut, 
                     color = cut)) +
  geom_density(alpha = 0.4) +
  labs(
    title = "Distribuição da dimensão x por Tipo de Corte",
    x = "Dimensão x do diamante", y = "Densidade",
    fill = "Tipo", color = "Tipo"
  ) +
  theme_minimal()

# Histograma + densidade juntos
ggplot(diamonds, aes(x = x, y = after_stat(density))) +
  geom_histogram(bins = 40, fill = "gray80", color = "white") +
  geom_density(color = "#534AB7", linewidth = 1) +
  theme_minimal()

Box plot comparando classes

ggplot(diamonds, aes(x = cut, y = x, fill = cut)) +
  geom_boxplot(alpha = 0.7, outlier.alpha = 0.2) +
  labs(
    title = "Dimensão x por qualidade do corte",
    x = "Tipo de corte", y = "Comprimento em x (mm)"
  ) +
  theme_minimal() +
  theme(legend.position = "none")  # legenda redundante com o eixo x

  • Se quisermos mostrar pequenos pontos próximos aos boxplots:
pequena_amostra <- diamonds |> 
  slice_sample(n = 200)

ggplot(diamonds, aes(x = cut, y = x, fill = cut)) +
  geom_boxplot(alpha = 0.5, outlier.shape = NA) +        # usa diamonds (dataset do ggplot)
  geom_jitter(data = pequena_amostra,                    # sobrescreve só para essa camada
              width = 0.2, alpha = 0.5, size = 1.5) +
  theme_minimal()

Gráfico de barras

Quando usar: frequência ou valor de uma variável categórica. Pergunta que responde: “Qual categoria é mais comum? Como se comparam os totais por grupo?”

Podemos usar o geom_bar() ou o gem_col().

  • Usamos o geom_bar() quando o R conta automaticamente as ocorrências:
ggplot(diamonds, aes(x = cut)) +
  geom_bar(fill = "#534AB7") +
  labs(title = "Distribuição por tipo de corte",
       subtitle = "Base de dados: diamond",
       x = "Tipo de corte", 
       y = "Frequência") +
  theme_minimal()

  • Usamos o geom_col() quando você já tem os valores calculados:
resumo_cortes <- diamonds |> 
  count(cut)
resumo_cortes |> 
  ggplot(aes(x = cut, y = n)) +
  geom_col()

  • melhorando o gráfico: ::: {.cell}
resumo_cortes |> 
  ggplot(aes(x = cut, y = n)) +
  geom_col(fill = "#534AB7", alpha = 0.85,
           color = "black") +
  geom_text(aes(label = n),
            vjust = -0.5, # acima da barra
            size = 4
            ) +
    labs(title = "Distribuição por tipo de corte",
       subtitle = "Base de dados: diamond",
       x = "Tipo de corte", 
       y = "Frequência") +
  theme_minimal()

:::

  • Se quisermos barras horizontais: ::: {.cell}
resumo_cortes |> 
  ggplot(aes(x = cut, y = n)) +
  geom_col(fill = "#534AB7", alpha = 0.85,
           color = "black") +
  geom_text(aes(label = n),
            vjust = -0.5, 
            size = 4
            ) +
  coord_flip() +
    labs(title = "Distribuição por tipo de corte",
       subtitle = "Base de dados: diamond",
       x = "Tipo de corte", 
       y = "Frequência") +
  theme_minimal() +
  theme(plot.title = element_text(face = "bold"))

:::

  • Barras agrupadas: ::: {.cell}
ggplot(diamonds, aes(x = cut, fill = color)) +
  geom_bar(position = "dodge") +   # lado a lado
  theme_minimal()

:::

  • Barras empilhadas: ::: {.cell}
grafico_barras <- ggplot(diamonds, aes(x = cut, fill = color)) +
  geom_bar(position = "fill") +
  scale_y_continuous(labels = scales::percent) +
  labs(x = "Tipo de corte", 
       y = "Proporção",
       title = "Tipo de corte vs. cor",
       subtitle = "Base de dados: diamonds",
       fill = "Cor") +
  theme_minimal() +
  theme(plot.title = element_text(face = "bold"),
        plot.subtitle = element_text(face = "italic",
                                     size = 8))

grafico_barras

:::

  • exportando o gráfico: ::: {.cell}
ggsave("grafico_barras.png",
       grafico_barras,
       width = 10,
       height = 6,
       dpi = 300)

:::

Gráfico de linhas

Quando usar: evolução de uma variável ao longo do tempo ou de uma sequência ordenada.

Pergunta que responde: “Como X mudou ao longo do tempo?”

# Exemplo
media_anual <- tibble(
  ano       = 2015:2023,
  media_mt  = c(492, 490, 507, 517, 523, 521, 529, 519, 524),
  media_lc  = c(493, 487, 498, 501, 502, 499, 504, 500, 505)
)
# Linha simples
ggplot(media_anual, aes(x = ano, y = media_mt)) +
  geom_line(color = "#534AB7", linewidth = 1) +
  geom_point(color = "#534AB7", size = 3) +  # pontos nas observações
  labs(
    title = "Evolução da Média de Matemática no ENEM",
    x = "Ano", y = "Média"
  ) +
  theme_minimal()

# Múltiplas linhas — formato longo (tidy)
library(tidyr)

media_longa <- media_anual |>
  pivot_longer(cols = c(media_mt, media_lc),
               names_to = "area",
               values_to = "media")

ggplot(media_longa, aes(x = ano, y = media, color = area)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2.5) +
  scale_color_manual(values = c("media_lc" = "#0F6E56", "media_mt" = "#534AB7"),
                     labels = c("Linguagens", "Matemática")) +
  labs(title = "Evolução das Médias do ENEM", x = "Ano", y = "Média", color = "Área") +
  theme_minimal()

⚠️ Gráfico de linhas só faz sentido quando o eixo X tem uma ordem natural (tempo, sequência). Para categorias nominais, use barras.

Gráficos Adicionais

Gráfico de violino

Combina o boxplot com a curva de densidade — mostra a forma completa da distribuição por grupo.

ggplot(diamonds, aes(x = cut, y = x, fill = cut)) +
  geom_violin(alpha = 0.7, trim = FALSE) +
  geom_boxplot(width = 0.1, fill = "white", outlier.shape = NA) +  # box no centro
  theme_minimal() +
  theme(legend.position = "none")

  • Mudando a orientação: ::: {.cell}
ggplot(diamonds, aes(x = cut, y = x, fill = cut)) +
  geom_violin(alpha = 0.7, trim = FALSE) +
  geom_boxplot(width = 0.1, fill = "white", outlier.shape = NA) +  # box no centro
  coord_flip() +
  theme_minimal() +
  theme(legend.position = "none")

:::

Heatmap

Excelente para mostrar padrões em uma matriz de duas variáveis categóricas.

# Média de cada área por região
heatmap_data <- diamonds |>
  group_by(cut, color) |>
  summarise(media = mean(x, na.rm = TRUE))
ggplot(heatmap_data, aes(x = cut, y = color, fill = media)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(media, 1)), size = 3) +
  scale_fill_distiller(palette = "RdYlGn", direction = 1) +
  labs(title = "Média de x (mm) por Corte e Cor", fill = "Média",
       y = "Cor", x = "Tipo de Corte") +
  theme_minimal()

Facetas

# facet_wrap: um painel por categoria
ggplot(diamonds, aes(x = x)) +
  geom_histogram(bins = 30, fill = "#534AB7", color = "white") +
  facet_wrap(~ cut, ncol = 3) +
  theme_minimal()

# facet_wrap: um painel por categoria
ggplot(diamonds, aes(x = x, fill = cut)) +
  geom_density(alpha = 0.8) +
  facet_wrap(~ cut, nrow = 5) +
  scale_fill_viridis_d() +
  theme_minimal()

# facet_grid: grade com duas variáveis
ggplot(diamonds, aes(x = x)) +
  geom_density(fill = "#534AB7", alpha = 0.5) +
  facet_grid(cut ~ color) +
  theme_minimal()