```{r}
<- function(...) {
minhas_cores <- c(
cores "laranja" = "#e59866",
"cinza" = "#979a9a",
"azul" = "#1b2631",
"vermelho" = "#641e16",
"agua" = "#d1f2eb",
"amarelo" = "#fcf3cf"
)<- c(...)
cols
if (is.null(cols))
return (cores)
cores[cols]
}```
Seguindo a regra de que se você tiver que explicar alguma coisa mais de 3 vezes, então você deve escrever um post sobre o assunto. E considerando que neste caso, estou explicando para mim mesmo como definir cores no ggplo2, achei melhor escrever este post para me ajudar a lembrar destas informações na próxima vez que precisar delas.
Para escrever este post utilizei as seguintes referências: (Aden-Buie 2019), (Jackson 2018) e (Hall 2022).
Estou usando este site para buscar os códigos das cores. Vou utilizar a seguintes cores:
Definindo funções para lidar com cores
Vamos definir uma função para lidar com as cores que desejamos.
A função acima permite acesso às cores:
```{r}
minhas_cores("vermelho", "amarelo")
```
vermelho amarelo
"#641e16" "#fcf3cf"
Podemos criar conjuntos diferentes de paletas de cores a partir das cores definidas na função minhas_cores.
```{r}
<- function(palette = "main", ...) {
minhas_paletas <- list(
minhas_paletas "main" = minhas_cores("laranja", "cinza", "vermelho", "amarelo"),
"highlight" = minhas_cores("agua", "azul", "amarelo"),
"two_colors" = minhas_cores("laranja", "vermelho")
)
minhas_paletas[[palette]]
}```
Isto permite selecionar um subgrupo de cores:
```{r}
minhas_paletas("main")
```
laranja cinza vermelho amarelo
"#e59866" "#979a9a" "#641e16" "#fcf3cf"
Podemos usar a função scales::show_col para mostrar as cores de uma forma elegante:
```{r}
#| fig-cap: "paleta Main"
#| label: fig-main-palette
::show_col(minhas_paletas("main"), cex_label = 2)
scales```
Usando as cores
Vamos utilizar as cores de Figure 2 em alguns gráficos.
```{r}
#| warning: false
#| message: false
library(tidyverse)
library(palmerpenguins)
```
Podemos referenciar as cores com a função minhas_cores definida anteriormente. Aqui, utilizamos o atributo fill de geom_col para definir a cor de preenchimento das barras do gráfico.
```{r}
#| fig-cap: "Barras preenchidas por cor selecionada"
#| label: fig-pn-1
<- palmerpenguins::penguins
penguins
%>%
penguins count(species) %>%
ggplot(aes(x = species, y = n)) +
geom_col(fill = minhas_cores("laranja")) +
labs(title = "Contagem de espécies") +
scale_y_continuous(expand = expansion(mult = c(0,0.1))) + # aumenta em 10% o eixo y positivo
theme_linedraw() +
theme(axis.ticks = element_blank(),
axis.title = element_blank(),
panel.grid.major.x = element_blank())
```
Através da função scale_fill_manual podemos usar diferentes cores para cada espécie de pinguim.
```{r}
#| fig-cap: "Cores das barras atribuídas pela ordem alfabética das espécies"
#| label: fig-pn-2
%>%
penguins count(species) %>%
ggplot(aes(x = species, y = n, fill = species)) +
geom_col() +
scale_fill_manual(values = unname(c(minhas_cores("laranja", "azul", "vermelho")))) +
labs(title = "Contagem de espécies") +
scale_y_continuous(expand = expansion(mult = c(0,0.1))) +
theme_linedraw() +
theme(axis.ticks = element_blank(),
axis.title = element_blank(),
panel.grid.major.x = element_blank())
```
No caso anterior as cores de cada espécie ficam dependentes da sequência com que as espécies são apresentadas - ordem alfabética - e da sequência das cores. Em alguns casos, gostaríamos que as cores ficassem atreladas às espécies específicas e não mudassem conforme a ordem dos atributos (o que é muito útil quando temos muitos gráficos) com os mesmos dados. Para isso, podemos associar cores às espécies nomeando um vetor com os nomes das espécies e os códigos das cores.
```{r}
#| fig-cap: "Vetor nomeado de cores"
#| label: fig-named-colors
<- minhas_cores("laranja", "azul", "vermelho")
penguins_colors <- setNames(penguins_colors, c("Gentoo", "Chinstrap", "Adelie"))
penguins_colors
penguins_colors::show_col(penguins_colors, cex_label = 2)
scales```
Gentoo Chinstrap Adelie
"#e59866" "#1b2631" "#641e16"
e utilizar este array da Figure 5 com a função scale_fill_manual. As cores são atribuídas conforme nomeamos cada elemento do vetor de cores (por exemplo, “Adele = #641e16 (vermelho)”. Se não tivéssemos feito isso, o sistema primeiro atribuiria as cores conforme a ordem alfabética como no código anterior e depois montaria o gráfico conforme a ordenação do fct_reorder.
```{r}
#| fig-cap: "Usando o vetor nomeado"
#| label: fig-vetor-nomeado
%>%
penguins count(species) %>%
ggplot(aes(x = fct_reorder(species, desc(n)), y = n, fill = species)) +
geom_col() +
scale_fill_manual(values = penguins_colors) +
labs(title = "Contagem de espécies") +
scale_y_continuous(expand = expansion(mult = c(0,0.1))) +
theme_linedraw() +
theme(axis.ticks = element_blank(),
axis.title = element_blank(),
panel.grid.major.x = element_blank())
```
Em alguns gráficos pode ser necessário termos mais cores do que as disponíveis na paleta de cores. É possível gerar novas paletas com um número maior de cores por interpolação através da função colorRampPalette. A função colorRampPalette devolve uma função para a qual passaremos o número de cores que gostaríamos de gerar a partir da interpolação das cores da paleta fornecida.
```{r}
#| fig-cap: "Usando _colorRampPalette_ para gerar paletas de cores maiores"
#| label: fig-pal-12
<- colorRampPalette(minhas_paletas("highlight"))(12)
penguins_12_colors
::show_col(penguins_12_colors, cex_label = 1)
scales```
Vamos colocar isto em uma função e testar.
```{r}
#| fig-cap: "Função que devolve função para gerar cores"
#| label: fig-gera-cores
<- function(palette = "main", reverse = FALSE, ...) {
penguin_pal <- minhas_paletas(palette)
pal
if (reverse) pal <- rev(pal)
colorRampPalette(pal, ...)
}::show_col(penguin_pal(palette = "two_colors", reverse = TRUE)(12))
scales```
Considere o seguinte gráfico que usa uma escala contínua de cores:
```{r}
#| fig-cap: "Diagrama de dispersão"
#| label: fig-scatter1
%>%
penguins filter(!is.na(bill_length_mm),
!is.na(bill_depth_mm)) %>%
ggplot(aes(bill_length_mm, bill_depth_mm, color = flipper_length_mm)) +
geom_point()
```
Gostaríamos de modificar a escala de cores utilizando as cores previamente definidas em minhas_cores e minhas_paletas.
Primeiro precisamos definir uma função que cria uma customização da função scale_color_continuous.
```{r}
#' Construtor de cores para escala contínua.
#'
#' @param palette nome da paleta definida em minhas_paletas
#' @param discrete Boolean indica se "color aesthetic" é discreto ou não
#' @param reverse Boolean indica se a paleta deve ter a sequência de cores invertida
#' @param ... outros parâmetros que serão passados para discrete_scale() ou
#' scale_color_gradientn(), uma das duas funções conforme o discrete é TRUE ou FALSE
#'
<- function(palette = "main", discrete = TRUE, reverse = FALSE, ...) {
scale_color_penguin <- penguin_pal(palette = palette, reverse = reverse)
pal
if (discrete) {
discrete_scale("colour", paste0("penguin_", palette), palette = pal, ...)
else {
} scale_color_gradientn(colours = pal(256), ...)
}
}
scale_color_penguin(palette = "highlight", discrete = FALSE)
```
<ScaleContinuous>
Range:
Limits: 0 -- 1
Vamos ajustar o último gráfico que fizemos para utilizar uma paleta de cores baseada na minhas_paletas(“highlight”).
```{r}
#| fig-cap: "Escala de cores customizada gerada a partir da paleta específica"
#| label: fig-scatter-2
%>%
penguins filter(!is.na(bill_length_mm),
!is.na(bill_depth_mm)) %>%
ggplot(aes(bill_length_mm, bill_depth_mm, color = flipper_length_mm)) +
geom_point() +
scale_color_penguin("two_colors", discrete = FALSE)
```
De forma similar à função color que fizemos, podemos implementar uma função para fill:
```{r}
#' Construtor de cores para escala contínua.
#'
#' @param palette nome da paleta definida em minhas_paletas
#' @param discrete Boolean indica se "color aesthetic" é discreto ou não
#' @param reverse Boolean indica se a paleta deve ter a sequência de cores invertida
#' @param ... outros parâmetros que serão passados para discrete_scale() ou
#' scale_color_gradientn(), uma das duas funções conforme o discrete é TRUE ou FALSE
#'
<- function(palette = "main", discrete = TRUE, reverse = FALSE, ...) {
scale_fill_penguin <- penguin_pal(palette = palette, reverse = reverse)
pal
if (discrete) {
discrete_scale("fill", paste0("penguin_", palette), palette = pal, ...)
else {
} scale_fill_gradientn(colours = pal(256), ...)
}
}```
```{r}
#| fig-cap: "Cores de preenchimento geradas a partir de paleta específica"
#| label: fig-barchart
%>%
penguins filter(!is.na(bill_length_mm),
!is.na(bill_depth_mm)) %>%
ggplot(aes(bill_length_mm, bill_depth_mm, color = flipper_length_mm)) +
geom_col() +
scale_color_penguin("two_colors", discrete = FALSE)
```
Este último gráfico não faz muito sentido, mas está aí apenas para exemplificar o uso da função scale_fill_penguin.
Referências
Citation
@misc{abreu2022,
author = {Abreu, Marcos},
title = {R tip: Como customizar cores no ggplot2},
date = {2022-10-27},
url = {https://abreums.github.io/posts/2022-10-27-r-tip-como-customizar-cores-no-ggplot2/},
langid = {pt-br}
}