5  Ggplot2

Hadley Wickham, junto com alguns colaboradoes, criaram o pacote ggplot2 com o intuíto de fornercer ao usuário do R uma ferramenta capaz de executar um “modelo poderoso para a produção de gráficos complexos de múltiplas camadas”.

Quais as principais vantagens do ggplot2?

Dito isto, existem algumas coisas que você não pode (ou não deve) fazer com o ggplot2, pois existem outros pacotes apropriados no R:

Qual é gramática dos gráficos?

Idéia básica: especificar separadamente blocos de construção de plotagem e combiná-los para criar qualquer tipo de exibição gráfica que você deseja.

Os blocos de construção de um gráfico incluem:

A estrutura básica de código para criar um ggplot é a seguinte:

ggplot(data = meu_data_frame, mapping = aes(x, y)) + geom_???()

Primeiro criamos um plot com a função ggplot. O primeiro argumento é o data, onde você especifica o tibble (base de dados) com suas variáveis. Depois vem o mapping. Nele você cria o “mapeamento” das variáveis, normalmente usando aes (de aesthetics), ou seja, você especifica dentre várias coisas, por exemplo, quais são as variáveis que serão representadas nos eixos x e ycores e símbolos usados para plotar os dados.

Depois da função ggplot, nós especificamos um geom. Por exemplo, geom_point para plotar pontos, geom_boxplot para um boxplot, etc. Para a lista completa de geoms e todas as outras opções do pacote, visite a página do projeto ggplot2.

Note que adicionamos um geom com um “+”. No ggplot2, nós criamos gráficos em camadas (layers), e adicionamos camada a camada com um “+”.

Com o intuito de explorarmos o pacote ggplot2, criem um projeto chamado ggplot2. Em seguida abram o Script Cap5 e façam a importação do arquivo seguro saude.txt, que contém variáveis referentes a clientes de um seguro de saúde, tais como sexo, imc, número de dependentes, fumante, região, valor das cobranças e se possuía plano de saúde anteriormente. Vale ressaltar que o arquivo possui as seguintes características:

#Visualizando o objeto
base_seguro
# A tibble: 1,338 × 8
   idade  sexo   imc num_dep fumante regiao cobrancas plano_anterior
   <dbl> <dbl> <dbl>   <dbl> <chr>    <dbl>     <dbl>          <dbl>
 1    31     2  20.4       0 Não          4     3260.             NA
 2    25     2  26.2       0 <NA>         1     2721.             NA
 3    21     2  36.9       0 Não          2     1917.             NA
 4    59     1  27.7       3 Não          3    14001.             NA
 5    58     2  23.3       0 Não          4    11346.             NA
 6    32     1  23.6       1 Não          3    17626.             NA
 7    50     1  26.2       2 Não          2    10494.             NA
 8    62     1  39.2       0 Não          4    13471.             NA
 9    62     1  33.0       3 Não          2    15612.             NA
10    39     2  24.5       2 Não          2     6710.              1
# ℹ 1,328 more rows

Após a importação do arquivo, iremos transformar em fatores as variáveis qualitativas, seguindo o dicionário da base.

#Transformando a variável sexo em factor 
base_seguro$sexo = factor(x = base_seguro$sexo, #vetor com os valores a serem rotulados
                          levels = c(1,2), #os valores distintos que aparecem
                          labels = c("Mulher", "Homem")) #os rótulos dos valores

#Transformando a variável fumante em factor
base_seguro$fumante = factor(x = base_seguro$fumante)

#Transformando a variável regiao em factor 
base_seguro$regiao = factor(x = base_seguro$regiao,
                            levels = c(1,2,3,4),
                            labels = c("Nordeste", "Noroeste", "Sudeste", "Sudoeste"))

#Transformando a variável plano_anterior em factor 
base_seguro$plano_anterior = factor(x = base_seguro$plano_anterior, #vetor com os valores a serem rotulados
                                    levels = c(0,1), #os valores distintos que aparecem
                                    labels = c("Não", "Sim")) #os rótulos dos valores

#Visualizando o objeto
base_seguro
# A tibble: 1,338 × 8
   idade sexo     imc num_dep fumante regiao   cobrancas plano_anterior
   <dbl> <fct>  <dbl>   <dbl> <fct>   <fct>        <dbl> <fct>         
 1    31 Homem   20.4       0 Não     Sudoeste     3260. <NA>          
 2    25 Homem   26.2       0 <NA>    Nordeste     2721. <NA>          
 3    21 Homem   36.9       0 Não     Noroeste     1917. <NA>          
 4    59 Mulher  27.7       3 Não     Sudeste     14001. <NA>          
 5    58 Homem   23.3       0 Não     Sudoeste    11346. <NA>          
 6    32 Mulher  23.6       1 Não     Sudeste     17626. <NA>          
 7    50 Mulher  26.2       2 Não     Noroeste    10494. <NA>          
 8    62 Mulher  39.2       0 Não     Sudoeste    13471. <NA>          
 9    62 Mulher  33.0       3 Não     Noroeste    15612. <NA>          
10    39 Homem   24.5       2 Não     Noroeste     6710. Sim           
# ℹ 1,328 more rows

5.1 Gráfico de dispersão (pontos)

Vamos começar produzindo um gráfico de dispersão (também chamado de gráfico de pontos) das variáveis imc e valor da cobrança. Para elaborar este gráfico, iremos usar a função ggplot e geom_point (esta segunda é a responsável por fazer o gráfico de pontos, isto é, o gráfico é definido em função do geom_ que escolhemos).

#Ativando o pacote
library(ggplot2)

#Criando um gráfico de dispersão
base_seguro |> #indicando o objeto que contém as variáveis
  ggplot(mapping = aes(x = imc, #especificando a variável do eixo x
                       y = cobrancas)) + #especificando a variável do eixo y 
  geom_point() #especificando o formato do gráfico
Warning: Removed 3 rows containing missing values or values outside the scale range
(`geom_point()`).

O gráfico resultante possui a variável imc no eixo x e cobranças no eixo y. O default do gráfico é possuir o fundo cinza e pontos da cor preta. Os rótulos dos eixos são preenchidos automaticamente com os nomes das variáveis. Entretanto, é possível alterarmos toda essa configuração básica, usando o argumento color na função ggplot, e as funções labs e theme.

#Criando um gráfico de dispersão
base_seguro |> #indicando o objeto que contém as variáveis
  ggplot(mapping = aes(x = imc, #especificando a variável do eixo x
                       y = cobrancas)) + #especificando a variável do eixo y
  geom_point(color = "red") + #especificando o formato do gráfico e a cor dos pontos
  labs(x = "índice de Massa Corpórea", #rótulo do eixo x
       y = "Valor cobrança (em reais)") + #rótulo do eixo y
  theme_classic() #modificando o tema do gráfico
Warning: Removed 3 rows containing missing values or values outside the scale range
(`geom_point()`).

Percebam que o color não se encontra dentro da função aes, isso porque a coloração dos pontos não está sendo definido por meio de uma variável e sim de uma cor específica. Qualquer definição do gráfico que dependa de uma variável, deverá ser realizada obrigatoriamente dentro da função aes.

É possível identificar os pontos de acordo com as categorias de outras variáveis, por exemplo, abaixo indicamos os pontos de acordo com o hábito de fumar.

#Criando um gráfico de dispersão
base_seguro |> #indicando o objeto que contém as variáveis
  ggplot(mapping = aes(x = imc, #especificando a variável do eixo x
                       y = cobrancas,#especificando a variável do eixo y 
                       color = fumante)) + #especificando a cor dos pontos
  geom_point() + #especificando o formato do gráfico
  labs(x = "índice de Massa Corpórea", #rótulo do eixo x
       y = "Valor cobrança (em reais)", #rótulo do eixo y
       color = "Fuma?") + #rótulo da legenda criada pelo color
  theme_classic() #modificando o tema do gráfico
Warning: Removed 3 rows containing missing values or values outside the scale range
(`geom_point()`).

Retirando os dados faltantes referente a variável fumante.

#Ativando o pacote
library(dplyr)

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
#Criando um gráfico de dispersão
base_seguro |> #indicando o objeto que contém as variáveis
  filter(!is.na(fumante)) |> #filtrando somente os indivíduos com informações sobre o hábito de fumar
  ggplot(mapping = aes(x = imc, #especificando a variável do eixo x
                       y = cobrancas,#especificando a variável do eixo y 
                       color = fumante)) + #especificando a cor dos pontos
  geom_point() + #especificando o formato do gráfico
  labs(x = "índice de Massa Corpórea", #rótulo do eixo x
       y = "Valor cobrança (em reais)", #rótulo do eixo y
       color = "Fuma?") + #rótulo da legenda criada pelo color
  theme_classic() #modificando o tema do gráfico
Warning: Removed 3 rows containing missing values or values outside the scale range
(`geom_point()`).

É possível identificar os pontos para categorias de variáveis qualitativas ou mesmo valores de variáveis quantitativas. Vejam os dois exemplos abaixo.

#Criando um gráfico de dispersão
base_seguro |> #indicando o objeto que contém as variáveis
  ggplot(mapping = aes(x = imc, #especificando a variável do eixo x
                       y = cobrancas,#especificando a variável do eixo y 
                       color = idade)) + #especificando a cor dos pontos
  geom_point() + #especificando o formato do gráfico
  labs(x = "índice de Massa Corpórea", #rótulo do eixo x
       y = "Valor cobrança (em reais)", #rótulo do eixo y
       color = "Idade") + #rótulo da legenda criada pelo color
  theme_classic() #modificando o tema do gráfico
Warning: Removed 3 rows containing missing values or values outside the scale range
(`geom_point()`).

#Criando um gráfico de dispersão
base_seguro |> #indicando o objeto que contém as variáveis
  ggplot(mapping = aes(x = imc, #especificando a variável do eixo x
                       y = cobrancas,#especificando a variável do eixo y 
                       size = idade)) + #especificando o tamanho dos pontos
  geom_point() + #especificando o formato do gráfico
  labs(x = "índice de Massa Corpórea", #rótulo do eixo x
       y = "Valor cobrança (em reais)", #rótulo do eixo y
       size = "Idade") + #rótulo da legenda criada pelo color
  theme_classic() #modificando o tema do gráfico
Warning: Removed 4 rows containing missing values or values outside the scale range
(`geom_point()`).

Com o pacote ggplot2 os gráficos viram objetos, isto é, podemos salvar os gráficos em objetos e posteriormente manipulá-los.

#Criando um gráfico de dispersão
graf1 = base_seguro |> #indicando o objeto que contém as variáveis
  filter(fumante == "Sim") |> #filtrando somente os fumantes
  ggplot(mapping = aes(x = imc, #especificando a variável do eixo x
                       y = cobrancas)) + #especificando a variável do eixo y 
  geom_point(color = "blue") + #especificando o formato do gráfico e a cor dos pontos
  labs(x = "índice de Massa Corpórea", #rótulo do eixo x
       y = "Valor cobrança (em reais)") + #rótulo do eixo y
  theme_classic() #modificando o tema do gráfico

#Visualizando o objeto
graf1
Warning: Removed 3 rows containing missing values or values outside the scale range
(`geom_point()`).

Se durante a apresentação do gráfico, alguém perguntasse se essa relação entre IMC e valor cobrado pelo plano se mnatém, é possível manipularmos o objeto já criado.

#Fatiando o gráfico usando uma variável
graf1 +
  facet_wrap(~regiao, #variável que vai ser usada para fatiar o gráfico
             nrow = 3) #número de linhas do gráfico
Warning: Removed 3 rows containing missing values or values outside the scale range
(`geom_point()`).

A presença dos NA no gráfico se dá, pois não foi feito nenhuma filtragem na construção do objeto graf1. É possível retirarmos, mas precisaremos refazer o gráfico.

#Fatiando o gráfico usando uma variável
base_seguro |> #indicando o objeto que contém as variáveis
  filter(fumante == "Sim", !is.na(regiao)) |> #filtrando somente indíduos que são fumantes e desconsiderando os indíviduos que não possuem informação sobre a região
  ggplot(mapping = aes(x = imc, #especificando a variável do eixo x
                       y = cobrancas)) + #especificando a variável do eixo y 
  geom_point(color = "blue") + #especificando o formato do gráfico e a cor dos pontos
  labs(x = "índice de Massa Corpórea", #rótulo do eixo x
       y = "Valor cobrança (em reais)") + #rótulo do eixo y
  theme_light() + #modificando o tema do gráfico
  facet_wrap(~regiao) #variável que vai ser usada para fatiar o gráfico
Warning: Removed 3 rows containing missing values or values outside the scale range
(`geom_point()`).

Também é possível fatiar o gráfico em função de duas variáveis.

#Fatiando o gráfico usando uma variável
base_seguro |> #indicando o objeto que contém as variáveis
  filter(fumante == "Sim", !is.na(regiao), !is.na(sexo)) |> #filtrando somente os fumantes
  ggplot(mapping = aes(x = imc, #especificando a variável do eixo x
                       y = cobrancas)) + #especificando a variável do eixo y 
  geom_point(color = "blue") + #especificando o formato do gráfico e a cor dos pontos
  labs(x = "índice de Massa Corpórea", #rótulo do eixo x
       y = "Valor cobrança (em reais)") + #rótulo do eixo y
  theme_minimal() + #modificando o tema do gráfico
  facet_grid(sexo ~ regiao)
Warning: Removed 3 rows containing missing values or values outside the scale range
(`geom_point()`).

5.2 Boxplot

Uma visualização útil para a detecção de dados discrepantes (outliers) em variáveis quantitativas é o boxplot.

A seguir vamos criar o boxplot da variável cobranças.

#Criando um boxplot
graf2 = base_seguro |> #indicando o objeto que contém as variáveis
  ggplot(mapping = aes(y = cobrancas)) + #especificando a variável do eixo y
  geom_boxplot() + #especificando o formato do gráfico
  labs(y = "Valor cobrança (em reais)") #rótulo do eixo y

#Visualizando o objeto
graf2
Warning: Removed 1 row containing non-finite outside the scale range
(`stat_boxplot()`).

É possível alterar a estética do gráfico como exemplificado abaixo.

#Criando um boxplot
graf2 = base_seguro |> #indicando o objeto que contém as variáveis
  ggplot(mapping = aes(y = cobrancas)) + #especificando a variável do eixo y
  geom_boxplot(fill = "green") + #especificando o formato do gráfico
  labs(y = "Valor cobrança (em reais)") + #rótulo do eixo y
  theme_classic() #modificando o tema do gráfico

#Visualizando o objeto
graf2
Warning: Removed 1 row containing non-finite outside the scale range
(`stat_boxplot()`).

Ou mesmo usar as facetas de fatiamento discutidas anteriormente.

#Visualizando o objeto
graf2 +
  facet_wrap(~regiao)
Warning: Removed 1 row containing non-finite outside the scale range
(`stat_boxplot()`).

5.3 Histogramas

Já os histogramas são gráficos úteis para avaliar o formato da distribuição de variáveuis quantitativas.

A seguir vamos criar o boxplot da variável cobranças.

#Criando um histograma
graf3 = base_seguro |> #indicando o objeto que contém as variáveis
  ggplot(mapping = aes(x = cobrancas)) + #especificando a variável do eixo x
  geom_histogram() + #especificando o formato do gráfico
  labs(x = "Valor cobrança (em reais)") #rótulo do eixo x

#Visualizando o objeto
graf3
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Warning: Removed 1 row containing non-finite outside the scale range
(`stat_bin()`).

É possível alterar a estética do gráfico como exemplificado abaixo.

#Criando um gráfico de barras
graf3 = base_seguro |> #indicando o objeto que contém as variáveis
  ggplot(mapping = aes(x = cobrancas)) + #especificando a variável do eixo x
  geom_histogram(fill = "pink", #especificando a cor do gráfico
                 bins = 10) + #especificando o número de intervalos
  labs(x = "Valor cobrança (em reais)", #rótulo do eixo x
       y = "Frequência") + #rótulo do eixo y
  theme_classic() #modificando o tema do gráfico

#Visualizando o objeto
graf3
Warning: Removed 1 row containing non-finite outside the scale range
(`stat_bin()`).

5.4 Gráfico de barras

Para construirmos um gráfico de barra, utilizaremos a função geom_bar.

#Criando um gráfico de barras
graf4 = base_seguro |> #indicando o objeto que contém as variáveis
  filter(!is.na(regiao)) |> #filtrando somente as linhas com dados de região
  ggplot(mapping = aes(x = regiao)) + #especificando a variável do eixo x
  geom_bar(fill = "purple") + #especificando o formato e a cor do gráfico
  labs(x = "Região", #rótulo do eixo x
       y = "Contagem") + #rótulo do eixo y
  theme_classic() #modificando o tema do gráfico

#Visualizando o objeto
graf4

No gráfico acima indicamos no aesthetics (aes) qual variável seria apresentada no eixo x somente. Se especificarmos o fill com uma cor no geom_bar, modificamos a cor do gráfico de barra.

Se o nosso desejo for criar gráficos para tabelas de contingência, podemos fazer isso usando o geom_bar e fazendo uma pequena modificação no aes.

#Criando um gráfico de barras empilhadas (contagem)
graf5 = base_seguro |> #indicando o objeto que contém as variáveis
  filter(!is.na(regiao),!is.na(sexo)) |> #filtrando somente as linhas com dados de região e sexo
  ggplot(mapping = aes(x = regiao, #especificando a variável do eixo x
                       fill = sexo)) + #especificando a variável que irá preencher as barras
  geom_bar() + #especificando o formato do gráfico
  labs(x = "Região", #rótulo do eixo x
       y = "Contagem", #rótulo do eixo y
       fill = "Sexo") + #rótulo da legenda
  theme_classic() #modificando o tema do gráfico

#Visualizando o objeto
graf5

Para as barras serem empilhadas, basta modificarmos position no geom_bar.

#Criando um gráfico de barras (lado a lado)
graf6 = base_seguro |> #indicando o objeto que contém as variáveis
  filter(!is.na(regiao),!is.na(sexo)) |> #filtrando somente as linhas com dados de região e sexo
  ggplot(mapping = aes(x = regiao, #especificando a variável do eixo x
                       fill = sexo)) + #especificando a variável que irá preencher as barras
  geom_bar(position = "dodge") + #especificando o formato do gráfico
  labs(x = "Região", #rótulo do eixo x
       y = "Contagem", #rótulo do eixo y
       fill = "Sexo") + #rótulo da legenda
  theme_classic() #modificando o tema do gráfico

#Visualizando o objeto
graf6

Para criarmos um gráfico de barras empilhadas com os percentuais ao invés das contagens, é preciso usar position = "fill".

#Criando um gráfico de barras empilhadas (porcentagem)
graf7 = base_seguro |> #indicando o objeto que contém as variáveis
  filter(!is.na(regiao),!is.na(sexo)) |> #filtrando somente as linhas com dados de região e sexo
  ggplot(mapping = aes(x = regiao, #especificando a variável do eixo x
                       fill = sexo)) + #especificando a variável que irá preencher as barras
  geom_bar(position = "fill") + #especificando o formato do gráfico
  labs(x = "Região", #rótulo do eixo x
       y = "Porcentagem", #rótulo do eixo y
       fill = "Sexo") + #rótulo da legenda
  theme_classic() #modificando o tema do gráfico

#Visualizando o objeto
graf7

É possível apresentarmos vários gráficos em uma mesma figura usando o pacote patchwork. Vejamos os exemplos abaixo.

#Ativando o pacote
library(patchwork)

#Juntando os objetos
graf5 + graf6

#Juntando os objetos
(graf5 | graf6) / graf7

5.5 Escalas

O pacote ggplot2 possui uma família de funções scale_. Estas funções servem para modificarmos escalas dos eixos dos gráficos ou mesmo escala de cores. A seguir apresentamos as principais.

Por exemplo, o graf7 possui o eixo y variando de 0 a 1, para que o mesmo seja apresentado em %, utilizaremos a função scale_y_continuous do ggplot2. Entretanto, também usaremos a função percent_format do pacote scales.

#Ativando o pacote
library(scales)

Attaching package: 'scales'
The following object is masked from 'package:readr':

    col_factor
#Modificando a escala do eixo y
graf7 +
  scale_y_continuous(labels = percent_format()) #colocando o eixo y em formato %

Ainda na função scale_y_continuous e scale_x_continuous, por meio do argumento breaks, é possível indicar quais os valores serão apresentados em cada eixo. Já a função coord_cartesian, usando o argumento, ylim nos permite especificar onde começa e onde termina o eixo y. Para modificarmos as cores, podemos recorrer a função scale_fill_manual.

#Criando um gráfico de barras (lado a lado)
graf6 = base_seguro |> #indicando o objeto que contém as variáveis
  filter(!is.na(regiao),!is.na(sexo)) |> #filtrando somente as linhas com dados de região e sexo
  ggplot(mapping = aes(x = regiao, #especificando a variável do eixo x
                       fill = sexo)) + #especificando a variável que irá preencher as barras
  geom_bar(position = "dodge") + #especificando o formato do gráfico
  labs(x = "Região", #rótulo do eixo x
       y = "Contagem", #rótulo do eixo y
       fill = "Sexo") + #rótulo da legenda
  theme_classic() + #modificando o tema do gráfico
  scale_fill_manual(values = c("#ff4500", "#268b07"))

#Visualizando o objeto
graf6

5.6 Desafio 1

  1. Usando o objeto base_seguro reproduza a figura abaixo. O boxplot foi feito usando a cor lightblue.

  1. Adicione no objeto base_seguro uma variável que classifica o IMC nas seguintes faixas: [15;25], (25;40], (40;55]. Plote um gráfico de barras para a variável criada. As barras devem ser vermelhas e não devem ser apresentados dados faltantes.
  2. Repruduza o gráfico abaixo.