{PT} Cowplot!
By Isabella Bicalho Frazeto in Graficos
February 13, 2022
Sobre o pacote
O Cowplot 🐄 é um pacote que foi
projetado para ser um add-on do ggplot
. As características mais
notáveis são os temas, o alinhamento, a organização de figuras em vários
painéis gráficos e funções que facilitam a anotação de plotagens ou
mesmo mesclar nossos gráficos com outras imagens. Meu objetivo neste
tutorial não é usar o pacote extensivamente, mas sim mostrar a você as
funções que eu mais uso ao trabalhar com gráficos.
Dados
Neste tutorial, usaremos a Tabela Nutricional do McDonald’s.
## Pacotes ----
library(ggplot2)
library(cowplot) #<<
library(dplyr)
## Dados ----
menu <- read.csv("menu.csv")
## Visualizar a tabela ----
glimpse(menu)
## Rows: 260
## Columns: 24
## $ Category <chr> "Breakfast", "Breakfast", "Breakfast", "~
## $ Item <chr> "Egg McMuffin", "Egg White Delight", "Sa~
## $ Serving.Size <chr> "4.8 oz (136 g)", "4.8 oz (135 g)", "3.9~
## $ Calories <int> 300, 250, 370, 450, 400, 430, 460, 520, ~
## $ Calories.from.Fat <int> 120, 70, 200, 250, 210, 210, 230, 270, 1~
## $ Total.Fat <dbl> 13, 8, 23, 28, 23, 23, 26, 30, 20, 25, 2~
## $ Total.Fat....Daily.Value. <int> 20, 12, 35, 43, 35, 36, 40, 47, 32, 38, ~
## $ Saturated.Fat <dbl> 5, 3, 8, 10, 8, 9, 13, 14, 11, 12, 12, 1~
## $ Saturated.Fat....Daily.Value. <int> 25, 15, 42, 52, 42, 46, 65, 68, 56, 59, ~
## $ Trans.Fat <dbl> 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, ~
## $ Cholesterol <int> 260, 25, 45, 285, 50, 300, 250, 250, 35,~
## $ Cholesterol....Daily.Value. <int> 87, 8, 15, 95, 16, 100, 83, 83, 11, 11, ~
## $ Sodium <int> 750, 770, 780, 860, 880, 960, 1300, 1410~
## $ Sodium....Daily.Value. <int> 31, 32, 33, 36, 37, 40, 54, 59, 54, 59, ~
## $ Carbohydrates <int> 31, 30, 29, 30, 30, 31, 38, 43, 36, 42, ~
## $ Carbohydrates....Daily.Value. <int> 10, 10, 10, 10, 10, 10, 13, 14, 12, 14, ~
## $ Dietary.Fiber <int> 4, 4, 4, 4, 4, 4, 2, 3, 2, 3, 2, 3, 2, 3~
## $ Dietary.Fiber....Daily.Value. <int> 17, 17, 17, 17, 17, 18, 7, 12, 7, 12, 6,~
## $ Sugars <int> 3, 3, 2, 2, 2, 3, 3, 4, 3, 4, 2, 3, 2, 3~
## $ Protein <int> 17, 18, 14, 21, 21, 26, 19, 19, 20, 20, ~
## $ Vitamin.A....Daily.Value. <int> 10, 6, 8, 15, 6, 15, 10, 15, 2, 6, 0, 4,~
## $ Vitamin.C....Daily.Value. <int> 0, 0, 0, 0, 0, 2, 8, 8, 8, 8, 0, 0, 0, 0~
## $ Calcium....Daily.Value. <int> 25, 25, 25, 30, 25, 30, 15, 20, 15, 15, ~
## $ Iron....Daily.Value. <int> 15, 8, 10, 15, 10, 20, 15, 20, 10, 15, 1~
Temas e background_grid
Apesar de ter conhecido o cowplot pela aplicabilidade em painéis, sempre acabo utilizando-o em outros tipos de projetos pela facilidade de lembrar os temas que desejo. Por exemplo, quando preciso de um gráfico mais clean, eu uso a função theme_half_open(), que tem um design simples, sem background e um estilo de eixo semiaberto (duas linhas no eixo do quadrantes inferiores esquerdos). Em seguida, vou aplicar esse tema em um gráfico scatter plot entre as variáveis “Total.Fat” e “Calories”:
ggplot(menu, aes(x = Calories,
y = Total.Fat,
color = Category)) +
geom_point() +
theme_half_open() ## < tema do cowplot
Veja que, com a ajuda do cowplot, rapidamente tivemos um gráfico
produzido com um tema clean e que está pronto para ser publicado! O
mais legal é que o tema ainda tem a opção de alterar o tamanho do texto
no título, no corpo do gráfico e assim por diante. Para obter mais
informações sobre essa função, execute o código: ?theme_half_open()
.
background_grid também é uma das minhas funções preferidas porque, bem 😅, é a função da qual me lembro quando quero colocar um plano de fundo (background 👌) no meu gráfico. Vamos executar dois exemplos com essa função:
## Gordura total vs. caloria
g_fat <- ggplot(menu, aes(x=Calories, y=Total.Fat, color = Category)) +
geom_point() +
theme_half_open() +
background_grid() # <<
g_fat
## Proteína vs. caloria
g_protein <- ggplot(menu, aes(x = Calories, y = Protein, color = Category)) +
geom_point() +
theme_half_open() +
background_grid() # <<
g_protein
Outro tema que eu costumo usar com frequência é o theme_minimal. De novo, o pacote me ganha pela usabilidade, logo que este tema possui “duas variantes”: theme_minimal_hgrid, que adiciona linhas na horizontal, e o theme_minimal_vgrid, que adiciona linhas na vertical. Por último, outro add-on que considero muito prático é o panel_border, que adicionar bordas ao panéis.
# Histograma para os dados de gordura total
## Com o theme_minimal_hgrid
hist_fat <- ggplot(menu, aes(x = Total.Fat, fill = Category)) +
geom_histogram() +
facet_grid(vars(Category), labeller = as_labeller(NULL)) +
theme_minimal_hgrid() + #<<
panel_border(color='black') + #<<,
theme(strip.text.y = element_blank())
hist_fat
# Histograma para os dados de proteína
## Com o theme_minimal_vgrid
hist_protein <- ggplot(menu, aes(x = Protein, fill = Category)) +
geom_histogram() +
facet_grid(vars(Category)) +
theme_minimal_vgrid() + #<<
panel_border(color='black') + #<<
theme(strip.text.y = element_blank())
hist_protein
Painéis
Por último, o cowplot tem um função semelhante ao par(mfrow)
do
base. A partir
dela, você é capaz de gerar painéis com vários gráficos em uma única
figura.
Vamos fazer três panéis: O primeiro para combinar os dois gráficos de dispersão (p_1), o segundo para combinar os dois gráficos de histograma (p_2) e o terceiro vai combinar o p_1 e o p_2 (p_3).
Painel I
Primeiro, observe que se usarmos apenas a função plot_grid()
sem levar
a legenda em consideração, ela ficará assim:
plot_grid(g_fat, g_protein, labels = c("A", "B"), label_size = 12)
Obviamente, o painel não é muito bom, pois os dois gráficos compartilham a mesma legenda (🤕). A solução então é a seguinde:
1. Fazer uma figura apenas com os gráficos e sem nenhuma legenda (prow).
prow <- plot_grid(
g_fat + theme(legend.position="none"),
g_protein + theme(legend.position="none"),
align = 'vh',
labels = c("A", "B"),
hjust = -1,
nrow = 1,
label_size = 12
)
2. Extrair a legenda usando get_legend (também do cowplot).
legend <- get_legend(
g_protein + theme()
)
3. Combinar num novo grid prow e a legenda.
p1 <- plot_grid(prow, legend)
p1
Painel II
Vamos repetir os mesmo passos realizados no Painel I, agora com os histogramas:
## Unir os gráficos
prow2 <- plot_grid(
hist_fat + theme(legend.position="none"),
hist_protein + theme(legend.position="none"),
align = 'vh',
labels = c("C", "D"),
hjust = -1,
nrow = 1,
label_size = 12
)
## Criar um objeto para a legenda
legend2 <- get_legend(
hist_protein + theme(legend.position = c(0, 0.55))
)
## Criar o gráfico
p2 <- plot_grid(prow2, legend2, nrow = 1)
p2
Painel III
Finalmente, o último painel 🤙! Nele incluiremos os quatro gráficos criados, no entanto, precisamos ter apenas uma legenda. Para tal, usaremos somente as combinações de gráficos sem legenda (prow e prow2) e a legenda criada para combinação com os histogramas (legend2). Faremos uma pequena edição na legenda 2 para ajeitar
plot_grid(prow, legend2, prow2, nrow = 2)
Para finalizar, precisamos arrumar as proporções dos gráficos no painel.
Para isso, vamos utilizar as funções rel_heights = c(t1, t2))
e
rel_widths = c(t1, t2)
, que alteram a altura e a largura,
respectivamente. Os argumentos da função correspondem ao tamanho que
queremos para cada figura. Os tamanhos devem ser inseridos na ordem em
que são incluídas os gráficos na função plot_grid()
.
p3 <- plot_grid(prow, legend2, prow2, nrow = 2,
rel_heights = c(8, 20, 6),
rel_widths = c(3, 3, 2))
p3
E fim 🥳!
Revisão por Marília Melo Favalesso.