How to change the color scale on a chart in R

Asked

Viewed 1,724 times

2

I have a bar chart of Brazilian states. The color of the state bar is according to the region that it belongs to.

inserir a descrição da imagem aqui The color scale was automatically set by ggplot2, I would like to exchange these colors, I tried to use the ggthemes, but it didn’t work.

Code used:

library(tidyverse)
library(openxlsx)

url <- httr::GET("https://xx9p7hp1p7.execute-api.us-east-1.amazonaws.com/prod/PortalGeral",
                 httr::add_headers("X-Parse-Application-Id" =
                                       "unAFkcaNDeXajurGB7LChj8SgQYS2ptm")) %>%
    httr::content() %>%
    '[['("results") %>%
    '[['(1) %>%
    '[['("arquivo") %>%
    '[['("url")

ms <- read.xlsx(url) %>%
    filter(municipio %in% NA)

ms$data <- as.Date(ms$data)

regiao <- ms %>%
    filter(data == max(data)) %>%
    select(regiao, estado) %>%
    unique()

for(i in 9:14) {
    ms[,i] <- as.numeric(ms[,i])
}

rm(url, i)

dados <- read_csv("https://brasil.io/dataset/covid19/caso_full/?place_type=state&is_repeated=False&format=csv") %>%
    select(-c(epidemiological_week, order_for_place, city, city_ibge_code, place_type,
              last_available_confirmed_per_100k_inhabitants,
              is_last, is_repeated)) %>%
    arrange(state, date)

names(dados) <- c("data", "estado", "casosAcumulados", "casosNovos", 
                  "obitosAcumulados", "obitosNovos", "mortalidade", "populacao")

regiao <- ms %>%
  filter(data == max(data)) %>%
  select(regiao, estado) %>%
  unique() 

dados <- merge(x = dados, y = regiao, by = "estado")

dados %>%
  filter(data == max(data) - 1) %>%
  arrange(desc(mortalidade)) %>%
  ggplot() +
  geom_col(aes(x = reorder(estado, - mortalidade), y = mortalidade, fill = regiao)) +
  geom_text(aes(x = estado, y = mortalidade, label = paste0(round(mortalidade, 3) * 100, "%")),
            vjust = -0.15, size = 2.5) +
  scale_y_continuous(labels = function(x) paste0(x*100, "%")) +
  scale_color_gradient(low = "blue", high = "red") +
  labs(x = "", y = "", fill = "") +
  theme(legend.position = "bottom") +
  theme(panel.background = element_rect(fill = "white", colour = "grey10")) +
  theme(panel.grid.major = element_line(colour = "gray", linetype = "solid"))  

1 answer

3


There are two main ways to define a color scale using ggplot2. One is manual and the other is using a preset color palette.

Setting colors manually

Each color should be defined manually. This definition can be done via code (RGB or hexadecimal) of the colors or by their name in English. The code definition allows a greater variation of colors, as not all of them have defined names. If the definition is made via color names, these names must be in English. Below I created a color scale, which is not necessarily beautiful or harmonious, which allows you to see this in detail:

dados %>%
    filter(data == max(data) - 1) %>%
    arrange(desc(mortalidade)) %>%
    ggplot() +
    geom_col(aes(x = reorder(estado, - mortalidade), y = mortalidade, fill = regiao)) +
    geom_text(aes(x = estado, y = mortalidade, label = paste0(round(mortalidade, 3) * 100, "%")),
                        vjust = -0.15, size = 2.5) +
    scale_y_continuous(labels = function(x) paste0(x*100, "%")) +
    scale_color_gradient(low = "blue", high = "red") +
    labs(x = "", y = "", fill = "") +
    theme(legend.position = "bottom") +
    theme(panel.background = element_rect(fill = "white", colour = "grey10")) +
    theme(panel.grid.major = element_line(colour = "gray", linetype = "solid")) +
    scale_fill_manual(values = c("red", "green", "blue", "orange", "cyan"))

inserir a descrição da imagem aqui

The R already comes with 657 pre-defined colors in your installation. Your names can be consulted through the function colors().

Setting colors through palettes

Just use the function scale_fill_brewer to set a color palette for your chart. In the example below I am using the palette Dark2:

dados %>%
    filter(data == max(data) - 1) %>%
    arrange(desc(mortalidade)) %>%
    ggplot() +
    geom_col(aes(x = reorder(estado, - mortalidade), y = mortalidade, fill = regiao)) +
    geom_text(aes(x = estado, y = mortalidade, label = paste0(round(mortalidade, 3) * 100, "%")),
                        vjust = -0.15, size = 2.5) +
    scale_y_continuous(labels = function(x) paste0(x*100, "%")) +
    scale_color_gradient(low = "blue", high = "red") +
    labs(x = "", y = "", fill = "") +
    theme(legend.position = "bottom") +
    theme(panel.background = element_rect(fill = "white", colour = "grey10")) +
    theme(panel.grid.major = element_line(colour = "gray", linetype = "solid")) +
    scale_fill_brewer(palette = "Dark2")

inserir a descrição da imagem aqui

Log in to help the function scale_fill_brewer to see what color palettes are available on ggplot2.

However, for a few years now, I have used another color palette for my graphics. She is called viridis and her colors are easily distinguishable by color-blind. As a teacher, I worry that my graphics are more inclusive and, with it, my students can differentiate what appears in the graphs. In addition, this scale works very well on black and white prints, unlike some other palette options.

dados %>%
    filter(data == max(data) - 1) %>%
    arrange(desc(mortalidade)) %>%
    ggplot() +
    geom_col(aes(x = reorder(estado, - mortalidade), y = mortalidade, fill = regiao)) +
    geom_text(aes(x = estado, y = mortalidade, label = paste0(round(mortalidade, 3) * 100, "%")),
                        vjust = -0.15, size = 2.5) +
    scale_y_continuous(labels = function(x) paste0(x*100, "%")) +
    scale_color_gradient(low = "blue", high = "red") +
    labs(x = "", y = "", fill = "") +
    theme(legend.position = "bottom") +
    theme(panel.background = element_rect(fill = "white", colour = "grey10")) +
    theme(panel.grid.major = element_line(colour = "gray", linetype = "solid")) +
    scale_fill_viridis_d()

inserir a descrição da imagem aqui

Unofficial pallets

Finally, there are unofficial color palettes made by R users who have more notion of color theory than I do. An option I really like is based on the color palettes of the films of the filmmaker Wes Anderson and can be downloaded here. Its use is also simple and combines the two methods previously seen:

library(wesanderson)
dados %>%
    filter(data == max(data) - 1) %>%
    arrange(desc(mortalidade)) %>%
    ggplot() +
    geom_col(aes(x = reorder(estado, - mortalidade), y = mortalidade, fill = regiao)) +
    geom_text(aes(x = estado, y = mortalidade, label = paste0(round(mortalidade, 3) * 100, "%")),
                        vjust = -0.15, size = 2.5) +
    scale_y_continuous(labels = function(x) paste0(x*100, "%")) +
    scale_color_gradient(low = "blue", high = "red") +
    labs(x = "", y = "", fill = "") +
    theme(legend.position = "bottom") +
    theme(panel.background = element_rect(fill = "white", colour = "grey10")) +
    theme(panel.grid.major = element_line(colour = "gray", linetype = "solid")) +
    scale_fill_manual(values = wes_palette("Zissou1"))

inserir a descrição da imagem aqui

Above I created a bar chart based on the colors of Marine Life with Steve Zissou, one of my favorite movies.


Note: all that was said above for color filling (fill) can be transposed to lines and contours (colour). I mean, just replace scale_fill_brewer for scale_colour_brewer in a line chart to obtain an analogous result.

  • 1

    Thank you for the excellent explanation!

  • 2

    Please. As there was no information about it here yet, I thought it would be interesting to create a complete answer as possible.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.