--- title: "Visualização de dados" subtitle: "Aula 3" author: "Bruno Montezano" institute: "Grupo Alliance
Programa de Pós-Graduação em Psiquiatria e Ciências do Comportamento
Universidade Federal do Rio Grande do Sul" date: last-modified date-format: long lang: pt-br execute: echo: true format: revealjs: incremental: true smaller: true theme: [default, ../assets/custom.scss] logo: "../assets/logo_ufrgs.png" bibliography: references.bib code-annotations: select --- ## Conteúdo de hoje - Pacote `ggplot2` - Gramática dos gráficos - Estética - Mapeamento - Gráficos básicos - Personalização de gráficos - Exemplos práticos - Extensões de `ggplot2` ## Que a Força esteja com você! ::: columns ::: {.column width="70%"} Para a aula de hoje, vamos usar os `dados_starwars`. Este conjunto de dados contém 14 variáveis de 87 personagens dos filmes da saga Star Wars. No decorrer da aula, vamos introduzir outras bases de dados para exemplificar cada tipo de gráfico. ::: ::: {.column width="30%"} ![](../assets/star_wars_poster.jpg) ::: ::: ## `dados_starwars` ```{r carregar-starwars} library(dados) library(dplyr) dados_starwars ``` ## `ggplot2` ![](../assets/logo_ggplot2.png){fig-align="center" width="45%"} ## Exemplos iniciais de `ggplot2` ::: columns ::: {.column width="50%"} ```{r exemplo-inicial-ggplot2-codigo} #| eval: false library(ggplot2) dados_starwars |> ggplot() + aes(x = massa, y = altura) + geom_point(color = "forestgreen", size = 3) + xlab("Massa (kg)") + ylab("Altura (cm)") + ggtitle("Altura e massa dos personagens") + theme_bw(base_size = 18) ```
```{r exemplo-inicial-ggplot2-codigo-com-filter} #| eval: false dados_starwars |> filter(!is.na(genero)) |> ggplot() + aes(x = massa, y = altura, color = genero) + geom_point(size = 4, alpha = 0.7) + xlab("Massa (kg)") + ylab("Altura (cm)") + ggtitle("Altura e massa dos personagens", "Estratificado por gênero") + theme_minimal(base_size = 20) + scale_color_discrete(name = "Gênero") ``` ::: ::: {.column width="50%"} ```{r exemplo-inicial-ggplot2-output} #| echo: false #| out-width: 100% #| fig-align: "center" library(ggplot2) ggplot(data = dados_starwars, aes(x = massa, y = altura)) + geom_point(color = "forestgreen", size = 3) + xlab("Massa (kg)") + ylab("Altura (cm)") + ggtitle("Altura e massa dos personagens") + theme_bw(base_size = 18) #+ #theme(plot.background = element_rect(fill = "#f0f1eb")) ggplot(data = dados_starwars |> filter(!is.na(genero)), aes(x = massa, y = altura, color = genero)) + geom_point(size = 4, alpha = 0.7) + xlab("Massa (kg)") + ylab("Altura (cm)") + ggtitle("Altura e massa dos personagens", "Estratificado por gênero") + theme_minimal(base_size = 20) + scale_color_discrete(name = "Gênero") #theme(plot.background = element_rect(fill = "#f0f1eb")) ``` ::: ::: ## Gramática de gráficos em camadas O pacote `ggplot2` segue duas filosofias que facilitam a compreensão do processo de construção de gráficos: ::: nonincremental - Um gráfico estatístico é uma representação visual dos dados por meio de atributos estéticos (posição, cor, forma, tamanho) de formas geométricas (pontos, linhas, curvas) [@thegram2005] - Um gráfico pode ser construído em camadas (sobreposição de elementos visuais) [@layered-grammar] ::: ## Camadas ::: {.panel-tabset} ## Canvas ```{r canvas} #| out-width: 75% #| fig-align: "center" dados_starwars |> ggplot() ``` ## Eixos ```{r eixos} #| out-width: 75% #| fig-align: "center" dados_starwars |> ggplot() + aes(x = massa, y = altura) ``` ## Geometria ```{r geometria} #| out-width: 75% #| fig-align: "center" dados_starwars |> ggplot() + aes(x = massa, y = altura) + geom_point() ``` ## Cor ```{r cor} #| out-width: 75% #| fig-align: "center" dados_starwars |> ggplot() + aes(x = massa, y = altura, color = genero) + geom_point() ``` ## Forma ```{r forma} #| out-width: 75% #| fig-align: "center" dados_starwars |> ggplot() + aes(x = massa, y = altura, shape = sexo_biologico) + geom_point() ``` ::: ## Por que o `+`? O `ggplot2`, diferentemente dos outros pacotes do Tidyverse, não usa o *pipe* (`|>`) porque o `ggplot2` surgiu [antes que o autor tomasse conhecimento do pipe](https://www.reddit.com/r/dataisbeautiful/comments/3mp9r7/comment/cvi19ly/?utm_source=share&utm_medium=web2x&context=3). . . . ![](../assets/hadley_sobre_pipe.png){fig-align="center"} ## Dica: Como escolher o gráfico mais adequado?
## Gráfico de pontos (dispersão) Geralmente usado para visualizar a associação de duas variáveis contínuas. . . . Exemplo: verificar a associação entre altura e massa nos personagens do Star Wars. . . . ```{r scatterplot-altura-massa} #| fig-align: "center" #| out.width: "70%" # O código abaixo gera a figura do slide dados_starwars |> # <1> filter(massa < 1000) |> # <2> ggplot() + # <3> aes(x = massa, y = altura) + # <4> geom_point() # <5> ``` 1. Usar os `dados_starwars` 2. Manter apenas observações
com menos de
1.000kg de massa 3. Iniciar o canvas do `ggplot2` 4. Mapear massa no eixo `x`
e altura no eixo `y` 4. Adicionar geometria de pontos
com `geom_point()` ## `ggplot2` é extremamente versátil
## `dados_gapminder` ::: columns ::: {.column width="55%"} Para aprender o próximo gráfico, vamos usar os `dados_gapminder`. Trata-se de um projeto sueco criado por Hans Rosling que coleta dados sobre diversas tendências globais. Na parte dos dados que vamos utilizar, temos informações de 1952 a 2007 (intervalos de 5 anos). Estes dados possuem 1.704 observações e 6 variáveis, sendo elas: `pais`, `continente`, `ano`, `expectativa_de_vida`, `populacao`, `pib_per_capita`. ::: ::: {.column width="45%"} ![](../assets/logo_gapminder.png) ::: ::: ## Exibindo `dados_gapminder` ```{r printar-gapminder} dados_gapminder ``` ## Gráfico de linhas Utilizamos o `geom_line()` para fazer gráficos de linhas. Eles são ótimos para representar *séries temporais*, ou seja, observações medidas repetidamente em intervalos de tempo. . . . Tal qual no gráfico de pontos, precisamos definir as posições $x$ e $y$ para construirmos os gráficos de linhas. . . . No próximo slide, vamos olhar um exemplo de gráfico de linha do PIB per capita do Brasil ao decorrer dos anos. ## PIB per capita do Brasil ::: {.panel-tabset} ## Linhas ```{r pib-do-brasil} #| fig-align: "center" #| out.width: "70%" dados_gapminder |> filter(pais == "Brasil") |> ggplot() + aes(x = ano, y = pib_per_capita) + geom_line() ``` ## Eixos ```{r pib-do-brasil-eixos} #| fig-align: "center" #| out.width: "65%" dados_gapminder |> filter(pais == "Brasil") |> ggplot() + aes(x = ano, y = pib_per_capita) + geom_line() + scale_x_continuous(breaks = seq(1952, 2007, 5)) + scale_y_continuous(labels = scales::dollar_format(prefix = "R$ ", decimal.mark = ",", big.mark = ".")) ``` ## Tema e rótulos ```{r pib-do-brasil-tema-rotulos} #| fig-align: "center" #| out.width: "50%" dados_gapminder |> filter(pais == "Brasil") |> ggplot() + aes(x = ano, y = pib_per_capita) + geom_line(linewidth = 2, color = "darkslateblue") + scale_x_continuous(breaks = seq(1952, 2007, 5)) + scale_y_continuous(labels = scales::dollar_format(prefix = "R$ ", decimal.mark = ",", big.mark = ".")) + labs(x = "Ano", y = "PIB per capita", title = "PIB per capita do Brasil ao passar dos anos", subtitle = "De 1952 a 2007", caption = "Fonte: Gapminder") + theme_minimal(base_size = 16, base_family = "Charter") ``` ::: ## Como os filmes da Pixar foram avaliados? ::: columns ::: {.column width="55%"} Para o próximo gráfico, vamos tentar responder a seguinte pergunta: "Segundo a CinemaScore, qual a nota mais recebida pelos filmes da Pixar?" Para isso, vamos usar outra base de dados do pacote `dados`, chamada `pixar_avalicao_publico`. ::: ::: {.column width="45%"} ![](../assets/logo_pixar.png) ::: ::: ## `pixar_avalicao_publico` ```{r mostrar-avaliacao-pixar} pixar_avalicao_publico ``` . . . ```{r count-avaliacao-cinema-score} pixar_avalicao_publico |> count(nota_cinema_score) # A função count() serve para contar os valores únicos de uma variável ``` ## Gráfico de barras O gráfico de barras é muito usado para apresentar a frequência de uma determinada categoria de uma variável. . . . No exemplo a seguir, acrescentamos o `ggplot2` ao código do slide anterior para criar um gráfico de barras com a frequência de cada nota (A-, A, A+) dos filmes da Pixar segundo o CinemaScore. ## Exemplo de gráfico de barras ```{r grafico-barras-cinema-score} #| out-width: 60% #| fig-align: "center" # Este código gera o gráfico abaixo pixar_avalicao_publico |> # <1> count(nota_cinema_score) |> # <2> ggplot() + # <3> aes(x = nota_cinema_score, y = n) + # <4> geom_col() # <5> ``` 1. Usar a base `pixar_avalicao_publico` 2. Contar número de filmes
em cada nota 3. Iniciar o canvas do `ggplot2` 4. Mapear os eixos `x` e `y` 5. Adicionar a geometria do
gráfico de barras ## Gráfico de barras após ajustes ::: {.panel-tabset} ## Código ```{r grafico-barras-cinema-score-ajustado} #| out-width: 60% #| fig-align: "center" #| eval: false # O código abaixo gera o gráfico do painel ao lado pixar_avalicao_publico |> # <1> rename(nota = nota_cinema_score) |> # <2> count(nota) |> # <3> mutate( # <4> nota = forcats::fct_na_value_to_level(nota, # <4> "Sem escore"), # <4> nota = factor(nota, # <5> levels = c("A-", "A", # <5> "A+", # <5> "Sem escore")), # <5> cor = dplyr::case_when(nota == "A" ~ "Colorido", # <6> .default = "Cinza") # <6> ) |> ggplot() + # <7> aes(x = nota, y = n, fill = cor) + # <8> geom_col(width = 0.5, show.legend = FALSE) + # <9> scale_fill_manual(values = c("gray25", "darkorange")) + # <10> labs(title = "A maioria dos filmes da Pixar (n = 13) receberam nota A.", # <11> x = "Nota segundo CinemaScore", # <11> y = "Número de filmes") + # <11> theme_classic(base_size = 18, base_family = "Charter") # <12> ``` 1. Pegar base da Pixar de
avaliação do público 2. Renomear variável
`nota_cinema_score` 3. Contar o número de
filmes com cada nota 4. Transformar `NA` no
valor "Sem escore" 5. Reordenar as notas
da menor para a maior 6. Criar variável para
colorir barra principal 7. Iniciar o canvas do `ggplot2` 8. Mapear variáveis do gráfico 9. Adicionar a geometria
do gráfico de barras,
retirar legenda e
mudar largura das barras 10. Modificar as cores
do preenchimento 11. Adicionar título e rótulos 12. Modificar tema,
tamanho e
família da fonte ## Gráfico ```{r grafico-barras-cinema-score-ajustado-output} #| out-width: 100% #| fig-align: "center" #| echo: false pixar_avalicao_publico |> count(nota_cinema_score) |> mutate(nota_cinema_score = forcats::fct_na_value_to_level( nota_cinema_score, "Sem escore"), nota_cinema_score = factor(nota_cinema_score, levels = c("A-", "A", "A+", "Sem escore")), cor = dplyr::case_when( nota_cinema_score == "A" ~ "Colorido", .default = "Cinza" )) |> ggplot() + aes(x = nota_cinema_score, y = n, fill = cor) + geom_col(width = 0.5, show.legend = FALSE) + scale_fill_manual(values = c("gray25", "darkorange")) + labs(title = "A maioria dos filmes da Pixar (n = 13) receberam nota A.", x = "Nota segundo CinemaScore", y = "Número de filmes") + theme_classic(base_size = 18, base_family = "Charter") ``` ::: ## Histograma Histogramas são úteis para avaliarmos a distribuição de uma variável numérica. . . . Para criar histogramas, usamos o `geom_histogram()`. Para isso, precisamos apenas do atributo $x$ (o eixo $y$ é construído de forma automática). . . . Na sequência, podemos observar um exemplo de histograma das notas dos filmes da Pixar no Rotten Tomatoes. . . . ```{r histograma-simples-rotten-tomatoes} #| fig-align: "center" #| out.width: "55%" pixar_avalicao_publico |> ggplot() + aes(x = nota_rotten_tomatoes) + geom_histogram() ``` ## Exemplo de histograma "mais bonito" ```{r histograma-rotten-tomatoes} #| fig-align: "center" #| out.width: "100%" pixar_avalicao_publico |> ggplot() + aes(x = nota_rotten_tomatoes) + geom_histogram(fill = "cyan4") + labs(x = "Nota segundo críticos do Rotten Tomatoes", y = "Contagem", title = "Como se distribuem as notas segundo os críticos do Rotten Tomatoes?", subtitle = "Dados de 24 filmes da Pixar", caption = "Fonte: Wikipedia") + theme_light(base_size = 16, base_family = "Charter") ``` ## Box plot Os box plots são úteis para estudar a distribuição de uma variável, especialmente ao comparar várias distribuições. . . . Para construir um box plot, usamos o `geom_boxplot()`. Para tal, usamos atributos $x$ e $y$, mapeando uma variável categórica para o atributo $x$. . . . ```{r boxplot-gapminder} #| fig-align: "center" #| out.width: "60%" dados_gapminder |> filter(ano == 1952) |> ggplot() + aes(x = continente, y = expectativa_de_vida) + geom_boxplot() ``` ## Box plot após ajustes ```{r boxplot-apos-ajustes} #| fig-align: "center" dados_gapminder |> filter(ano == 1952) |> ggplot() + aes(x = continente, y = expectativa_de_vida, color = continente) + geom_boxplot(show.legend = FALSE) + theme_classic(base_size = 16, base_family = "Charter") + labs(x = "Continente", y = "Expectativa de vida (em anos)", title = "Como se distribuía a expectativa de vida em cada continente em 1952?", caption = "Fonte: Gapminder") + annotate("text", x = 1, y = 65, label = "Em 1952,\na África tinha\numa expectativa\nde vida\nde 38,8 anos.", size = 5, family = "Charter") ``` ## Títulos, labels e escalas Para colocar títulos ou trocar os labels (rótulos) dos atributos, utilizamos a função `labs()`. . . . Para mudar as escalas (textos e quebras), usamos as funções da família `scale_[estética]_[opção]()`. . . . Para definir qual porção do gráfico deve ser mostrada (limites), podemos usar as funções `xlim()` e `ylim()`. ## Cores Para escolher manualmente as cores que coloriram ou preencheram um plot, use as funções `scale_color_manual()` ou `scale_fill_manual()`. . . . Para trocar o nome das legendas geradas por atributos de cor, use as funções `scale_color_discrete()` ou `scale_fill_discrete()`. ## Temas Como vocês devem ter percebido, o `ggplot2` traz consigo alguns temas prontos a partir de funções da família `theme_[estilo_do_tema]`. . . . Você também pode criar o seu próprio tema usando a função `theme()`. Não teremos como ver durante as aulas, pois requer um pouco mais de conhecimento técnico, mas é um processo divertido de aprender! ## Dica: Extensões do `ggplot2` * O `ggplot2` é muito potente, mas não possui todos os gráficos possíveis * Por conta disso, a comunidade desenvolve extensões que vão desde pacotes com novos temas ou cores, geometrias, eixos ou até a [possibilidade de criar calendários customizados](https://r-coder.com/calendar-plot-r/) 😂 * A equipe do Tidyverse mantém uma [lista curada de extensões do `ggplot2`](https://exts.ggplot2.tidyverse.org/gallery/) . . . ```{r calendario-mes-abril} #| echo: false #| fig-align: "center" #| out.width: "60%" calendR::calendR(year = 2023, month = 04, special.days = c(17, 24), special.col = "#bfe2f2", low.col = "white", title = "Aulas de R no mês de abril de 2023", subtitle = "Exclusivas para o grupo de pesquisa Alliance", weeknames = c("Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"), lunar = FALSE) ``` ## Tarefa de casa * A partir dos dados `pinguins` do pacote `dados`, crie: - Um gráfico de pontos (dispersão) - Um box plot (variável numérica estratificada por uma variável categórica) - Um histograma * Escolha um dos seus gráficos para ajustá-lo e deixá-lo visualmente mais agradável! - Ajustar rótulos, tamanho da fonte, cores, adicionar título, e o que mais você achar importante - Lembre-se da função `labs()` e família `theme_[estilo_do_tema]()` ## Dica de leitura sobre visualização ::: columns ::: {.column width="50%"} * [Data Visualization: A Practical Introduction](https://socviz.co/) - Como criar visualizações efetivas - Quais visualizações funcionam e quais não - Como criar vários tipos de gráficos em `ggplot2` - Como refinar os gráficos para apresentação ::: ::: {.column width="50%"} ![](../assets/capa_data_visualization.jpg){fig-align="center" width=90%} ::: ::: ## Referências ::: {#refs} :::