O [ggplot2] (https://ggplot2.tidyverse.org/) é um pacote para a linguagem de programação estatística R
É uma ferramenta cheia de funcionalidades, construída para visualização de dados
Esse material foi concebido como apoio didático à “Mentoria de ggplot” ministrada ao Pod Porto Alegre das 500 MUlhes Cientistas no ano de 2021
A ideia é que usuários iniciantes consigam produzir todos os gráficos
Para a construção desse material foram adaptados os exemplos disponíveis em: [Simple Gantt charts in R with ggplot2 and Microsoft Excel - Cédric Scherer] (https://www.cedricscherer.com/2019/08/05/a-ggplot2-tutorial-for-beautiful-plotting-in-r/)
O R é uma linguagem de programação muito poderosa e amplamente utilizada para análise de dados.
Contudo, a maior parte de suas funcionalidades avançadas estão disponíveis através de pacotes.
Os pacotes no R, como o “ggplot2”, são coleções de funções, dados e documentação que ampliam as capacidades básicas do R.
Não é preciso baixar e instalar mais do que uma vez os pacotes no R. Contudo, cada vez que o R é reiniciado é preciso carregar os pacotes que serão utilizados nas análises.
# Nessa mentoria, usamos os pacotes "tidyverse" e "ggplot2"
# Instalar:
# install.packages("tidyverse") # remover o comentário (#) caso precise instalar
# install.packages("ggplot2")
# Carregar:
library("tidyverse")
Nesse exemplo vamos usar os dados do Estudo Nacional de Morbidade e Mortalidade sobre Poluição do Ar dos Esyados Unidos (National Morbidity and Mortality Air Pollution Study - NMMAPS).
Para fins didáticos os dados foram restringidos para Chicago entre os anos 1997 e 2000.
A matriz está em fromato .csv e hospedada em um diretório online. Basta seguir o código para importar automaticamente.
chic <- readr::read_csv("https://avilaf.github.io/dados/chicago-nmmaps-custom.csv")
## Rows: 1461 Columns: 10
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (3): city, season, month
## dbl (6): temp, o3, dewpoint, pm10, yday, year
## date (1): date
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# ao usar "::namespace" (não é necessério carregar o pacote)
# é uma função interessante quando usamos mtos pacotes em um único script
# ou um pacote é utilizado somente para uma função pontual
tibble::glimpse(chic) # para transpor e visualizar os dados
## Rows: 1,461
## Columns: 10
## $ city <chr> "chic", "chic", "chic", "chic", "chic", "chic", "chic", "chic…
## $ date <date> 1997-01-01, 1997-01-02, 1997-01-03, 1997-01-04, 1997-01-05, …
## $ temp <dbl> 36.0, 45.0, 40.0, 51.5, 27.0, 17.0, 16.0, 19.0, 26.0, 16.0, 1…
## $ o3 <dbl> 5.659256, 5.525417, 6.288548, 7.537758, 20.760798, 14.940874,…
## $ dewpoint <dbl> 37.500, 47.250, 38.000, 45.500, 11.250, 5.750, 7.000, 17.750,…
## $ pm10 <dbl> 13.052268, 41.948600, 27.041751, 25.072573, 15.343121, 9.3646…
## $ season <chr> "Winter", "Winter", "Winter", "Winter", "Winter", "Winter", "…
## $ yday <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18…
## $ month <chr> "Jan", "Jan", "Jan", "Jan", "Jan", "Jan", "Jan", "Jan", "Jan"…
## $ year <dbl> 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1…
class(chic) # qual a classe do objeto "chic"?
## [1] "spec_tbl_df" "tbl_df" "tbl" "data.frame"
head(chic, 10) # visualizar o cabeçalho
## # A tibble: 10 × 10
## city date temp o3 dewpoint pm10 season yday month year
## <chr> <date> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <chr> <dbl>
## 1 chic 1997-01-01 36 5.66 37.5 13.1 Winter 1 Jan 1997
## 2 chic 1997-01-02 45 5.53 47.2 41.9 Winter 2 Jan 1997
## 3 chic 1997-01-03 40 6.29 38 27.0 Winter 3 Jan 1997
## 4 chic 1997-01-04 51.5 7.54 45.5 25.1 Winter 4 Jan 1997
## 5 chic 1997-01-05 27 20.8 11.2 15.3 Winter 5 Jan 1997
## 6 chic 1997-01-06 17 14.9 5.75 9.36 Winter 6 Jan 1997
## 7 chic 1997-01-07 16 11.9 7 20.2 Winter 7 Jan 1997
## 8 chic 1997-01-08 19 8.68 17.8 33.1 Winter 8 Jan 1997
## 9 chic 1997-01-09 26 13.4 24 12.1 Winter 9 Jan 1997
## 10 chic 1997-01-10 16 10.4 5.38 24.8 Winter 10 Jan 1997
# Note que temos muitos tipos de variáveis: categóricas, numéricas, discretas, contínuas...
Antes de continuar…
O ggplot2 usa uma sintaxe de camadas que permite construir gráficos de forma incremental e modular. Cada camada adiciona um elemento ao gráfico, como os dados, mapeamentos estéticos (cores, tamanhos, etc.) e geometrias (pontos, barras, linhas, etc.). Isso torna o código mais legível e fácil de modificar.
1 - Data: Os dados brutos que você deseja plotar.
2 - Geometries ‘geom_’: As formas geométricas que representarão os dados.
3 - Aesthetics ‘aes()’: Estética dos objetos geométricos e estatísticos, como posição, cor, tamanho, forma e transparência
4 - Scales ‘scale_’: Relacionar os dados com as dimensões estéticas, como intervalo de dados para largura do gráfico ou valores de fator para cores.
5 - Statistical transformations ‘stat_’: Resumir estatisticamente os dados, como calcular quantis, curvas ajustadas e somas.
6 - Coordinate system ‘coord_’: Transformação usada para mapear coordenadas de dados no espaço de plotagem de dados.
7 - Facets ‘facet_’: A disposição dos dados em uma grade de gráficos.
8 - Visual themes ‘theme()’: Os padrões visuais gerais de um gráfico, como plano de fundo, grades, eixos, fonte padrão, tamanhos e cores.
# o primeiro passo é definir o conjunto de dados (data) e os eixos
# na função a seguir temos os dados + argumento 'aes' posisicionais (x e y)
ggplot(data = chic,
aes(x = date,
y = temp))
Note que não foi definida uma camada com a plotagem dos dados propriamente ditos.
# também é possível atribuir a plotagem a um ggobejto ('g'<-)
(g <- ggplot(chic, aes(x = date, y = temp))) # base
# e usar esse objeto para acrescentar camadas na plotagem:
g + geom_point() # gráfico de dispersão de pontos
g + geom_line() # gráfico de linhas
g + geom_line() + geom_point() # linhas e pontos
Podemos fazer algumas edições estéticas na propriedade “geom”, como alterar cores e formas.
# para alterar as cores:
g + geom_point(color = "firebrick",
shape = "diamond",
size = 2)
# Para mais opções decores:
# http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf
# paletas de cores: RColorBrewer::display.brewer.all()
# RColorBrewer::brewer.pal(n = 3, name = "Set1")
# com sobreposição de camadas é só manter o padrão:
g + geom_point(color = "firebrick",
shape = "diamond",
size = 2) +
geom_line(color = "firebrick",
linetype = "dotted",
size = .3)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Ajustar o tema também altera o visual do gráfico. Existem muitas opções de temas disponóveis.
# ajustar o tema para bw
theme_set(theme_bw())
g + geom_point(color = "firebrick")
Existem alguns pacotes com temas prontos, como “ggthemes” e “hrbrthemes”.
Além disso, cada camada pode utilizar uma cor independente.
# mudar a cor das linhas e pontos:
ggplot(chic, aes(x = date, y = o3)) +
geom_line(color = "gray") +
geom_point(color = "darkorange2") +
labs(x = "Ano", y = "Ozônio")
# Duas grafias diferentes para os mesmos resultados:
# 1
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)")
# 2
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
xlab("Ano") +
ylab("Temperatura (°F)")
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Year",
y = expression
(paste("Temperatura (", degree ~ F, ")"^"(O exemplo é Norte Americano, então não usamos graus Celsius!)")))
# dentro de 'theme()'
# modificar o elemento 'axis.title = ' ou 'axis.title.x' e 'axis.title.y'
# dentro de 'element_text = ':
# size
# color
# face (bol, italic, bold.italic)
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(axis.title = element_text(size = 15, color = "firebrick",
face = "italic"))
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(axis.title.x = element_text(color = "sienna", size = 15),
axis.title.y = element_text(color = "orangered", size = 15))
# ('axis.title = ' + 'axis.title.y')
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(axis.title = element_text(color = "sienna", size = 15, face = "bold"),
axis.title.y = element_text(face = "bold.italic"))
Esta parte é semelhante ao tópico anterior, mas com o argumento ‘axis.text’ ou ‘axis.text.x’ e’axis.text.y’
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (ºF)") +
theme(axis.text = element_text(color = "dodgerblue", size = 12),
axis.text.x = element_text(face = "italic"))
# 'angle" dentro de 'theme(axis.text = (anlge = ))'
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(axis.text.x = element_text(angle = 50, vjust = 1, hjust = 1, size = 12))
# argumento labs()
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = NULL, y = "")
# Observe que NULL remove o elemento (similarmente a element_blank()) enquanto aspas vazias "" manterão o espaçamento para o título do eixo e simplesmente não imprimirão nada.
# com a camada theme()
# argumento vjust (alinhamento vertical)
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(axis.title.x = element_text(vjust = 0, size = 15),
axis.title.y = element_text(vjust = 2, size = 15))
“top”, “right”, “bottom” e “left” são argumentos que podem ser usados na função “theme()” do pacote ggplot2 para controlar a posição dos títulos, rótulos e legendas em um gráfico. Especificamente:
Os argumentos são dispostos em ordem top, right, bottom, left ou seja: margin(t, r, b, l). Para lembrar dessa sequência usamos a palavra t-r-oub-l-e.
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(axis.title.x = element_text(margin = margin(t = 10), size = 15),
axis.title.y = element_text(margin = margin(r = 10), size = 15))
Com subsetting
# 'subsetting': (realiza um subconjunto dos dados primeiro)
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
ylim(c(0, 50))
## Warning: Removed 777 rows containing missing values or values outside the scale range
## (`geom_point()`).
Outra opção (zooming):
# zooming: (sem espaço)
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
coord_cartesian(ylim = c(0, 50))
Um exemplo com gráfico boxlot:
Opção subsetting
# zoom
ggplot(chic, aes(x = factor(year), y = temp)) +
geom_boxplot(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
coord_cartesian(ylim = c(0, 50))
Outra opção (zooming):
# subset (recorta os dados antes da plotagem )
ggplot(chic, aes(x = factor(year), y = temp)) +
geom_boxplot(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
ylim(c(0, 50))
## Warning: Removed 777 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
g +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
ggtitle("Temperaturas en Chicago")
Para dadicionar mais argumentos use a função labs()
# labs() Para adicionar mais argumentos:
g +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)",
title = "Temperaturas em Chicago",
subtitle = "Padrão sazonal de temperaturas diárias de 1997 a 2001",
caption = "Dados: NMMAPS",
tag = "Fig. 1")
A função theme() funciona para: plot.subtitle, plot.caption, plot.caption, legend.title, legend.text, and axis.title and axis.text
g +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)",
title = "Temperaturas en Chicago") +
theme(plot.title = element_text(face = "bold",
margin = margin(10, 0, 10, 0),
size = 14))
Aqui usamos a função hjust()
# hjust
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = NULL,
title = "Temperaturas em Chicago",
caption = "Dados: NMMAPS") +
theme(plot.title = element_text(hjust = 1, size = 16, face = "bold.italic"))
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Year", y = "Temperature (?F)") +
ggtitle("Temperatures in Chicago\nfrom 1997 to 2001") +
theme(plot.title = element_text(lineheight = .8, size = 16))
Uma opção para atribuir legendas é o argumento color()
# color = season
ggplot(chic,
aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)")
Pode ser realizado com a função theme() definida como theme(legend.position = “none”)
ggplot(chic,
aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(legend.position = "none")
# Sem nenhuma legenda
Aqui vamos remover a legenda para as cores e manter a leganda para as formas ajustando guides(color = “none”)
ggplot(chic,
aes(x = date, y = temp,
color = season, shape = season)) +
geom_point() +
labs(x = "Ano", y = "Temperature (°F)") +
guides(color = "none")
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(legend.title = element_blank())
Temos algumas opções:
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(legend.position = "top")
Também é possível podicionar a legenda dentro do gráfico
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)",
color = NULL) +
theme(legend.position.inside = c(.15, .15),
legend.background = element_rect(fill = "transparent"))
No exemplo a seguir deixamos a legenda na direção horizontal
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Year", y = "Temperature (?F)") +
theme(legend.position = c(.5, .97),
legend.background = element_rect(fill = "transparent")) +
guides(color = guide_legend(direction = "horizontal"))
## Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
## 3.5.0.
## ℹ Please use the `legend.position.inside` argument of `theme()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Para alteraro estílo do título da legenda adicionamos o argumento legend.title em theme()
# theme(legend.title = ())
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(legend.title = element_text(color = "chocolate",
size = 14, face = "bold"))
Além disso é possível mudar o texto do título da legenda
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)",
color = "Estações\nindicadas\npor cores:") +
theme(legend.title = element_text(color = "chocolate",
size = 14, face = "bold"))
# aqui \n é usado para qiebra de texto
# determinar a ordem dos níveis antes da plotagem
chic$season <-
factor(chic$season,
levels = c("Winter", "Spring", "Summer", "Autumn"))
# plotar
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)")
Caso queira definir cores específicas para os níveis.
# scale_color_discrete()
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)") +
scale_color_discrete(
name = "Seasons:",
labels = c("Mar-May", "Jun-Aug", "Sep-Nov", "Dec-Feb")
) +
theme(legend.title = element_text(
color = "chocolate", size = 14, face = 2
))
Como opção estética, você pode colocar cores de preenchimento nos ítens da legenda
# legend.key()
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(legend.key = element_rect(fill = "darkgoldenrod1"),
legend.title = element_text(color = "chocolate",
size = 14, face = 2)) +
scale_color_discrete("Seasons:")
Ou remover o preenchimento
# sem preenchimento:
# fill = NA or fill = "transparent"
# alterar o tamanho dos simbolos da legenda:
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(legend.key = element_rect(fill = NA),
legend.title = element_text(color = "chocolate",
size = 14, face = 2)) +
scale_color_discrete("Estações:") +
guides(color = guide_legend(override.aes = list(size = 6)))
Quando estamos mapeando uma variável contínua, o ggplot por default determina um gradiente
ggplot(chic,
aes(x = date, y = temp, color = temp)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)", color = "Temperatura (°F)")
Mas podemos forçar a legenda a mostrar valores discretos com guide_legend()
ggplot(chic,
aes(x = date, y = temp, color = temp)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)", color = "Temperatura (°F)") +
guides(color = guide_legend())
Também podemos limtar as escalas
ggplot(chic,
aes(x = date, y = temp, color = temp)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)", color = "Temperatura (°F)") +
guides(color = guide_bins())
Ou utilizar uma escala de cores discretas:
ggplot(chic,
aes(x = date, y = temp, color = temp)) +
geom_point() +
labs(x = "Ano", y = "Temperatura (°F)", color = "Temperatura (°F)") +
guides(color = guide_colorsteps())
Planos de fundo e linhas podem ser alterados dentro da função theme()
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "#1D8565", size = 2) +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(panel.background = element_rect(
fill = "#64D2AA", color = "#64D2AA", linewidth = 2)
)
Observe que a cor verdadeira - o contorno do fundo do painel - não vai mudar nesse exemplo, mesmo que a tenhamos especificado. Isso ocorre porque há uma camada em cima de painel.background, ou seja, painel.border
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "#1D8565", size = 2) +
labs(x = "Year", y = "Temperature (?F)") +
theme(panel.border = element_rect(
fill = "#64D2AA99", color = "#64D2AA", size = 2)
)
## Warning: The `size` argument of `element_rect()` is deprecated as of ggplot2 3.4.0.
## ℹ Please use the `linewidth` argument instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Para alterar as çinhas usamos panel.grid() ou, para cada conjunto de linhas separadamente: panel.grid.major() e panel.grid.minor()
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(panel.grid.major = element_line(color = "gray10", linewidth = .5),
panel.grid.minor = element_line(color = "gray70", linewidth = .25))
Podemos também detalhas mais
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(panel.grid.major = element_line(size = .5, linetype = "dashed"),
panel.grid.minor = element_line(size = .25, linetype = "dotted"),
panel.grid.major.x = element_line(color = "red1"),
panel.grid.major.y = element_line(color = "blue1"),
panel.grid.minor.x = element_line(color = "red4"),
panel.grid.minor.y = element_line(color = "blue4"))
## Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
## ℹ Please use the `linewidth` argument instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Podemos também remover as linhas
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(panel.grid.minor = element_blank())
Todas as linhas
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (ºF)") +
theme(panel.grid = element_blank())
# ou theme_minimal()
Aqui podemos modificar com panel.background() e plot.backgroun()
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(panel.background = element_rect(fill = NA),
plot.background = element_rect(fill = "gray60",
color = "gray30", size = 2))
Mais um exemplo
ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Ano", y = "Temperatura (°F)") +
theme(plot.background = element_rect(fill = "gray60"),
plot.margin = margin(t = 1, r = 3, b = 1, l = 8, unit = "cm"))
Espero que esse material tenha ajudado de alguma forma e fico à disposição para esclarecer o que for necessário.
Dra. Fernanda Rodrigues de Avila https://avilaf.github.io/