• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Data Viz with Python and R

Learn to Make Plots in Python and R

  • Home
  • Seaborn
  • Matplotlib
  • ggplot2
  • Altair
  • About
    • Privacy Policy
  • Visualizing Activation Functions in Neural Networks
  • Confusion Matrix Calculator
  • Visualizing Dropout Rate in Neural Network
  • Visualizing Loss Functions in Neural Networks
  • Show Search
Hide Search

Introduction to Color Palettes in R with RColorBrewer

datavizpyr · January 22, 2020 ·

Last updated on September 6, 2025

Choosing colors for data visualization in R is hard—especially if you want charts that are clear, consistent, and inclusive. The RColorBrewer package (based on a href=”http://colorbrewer2.org/”>ColorBrewer2) gives you carefully designed sequential, diverging, and qualitative palettes that map well to how people perceive data.

In this guide, you’ll learn when to use each palette type and how to apply them in ggplot2, including color-blind friendly options and practical tips you can rely on.

Table of contents
  1. What is RColorBrewer?
  2. Palette Types & When to Use Them
    1. Sequential
    2. Diverging
    3. Qualitative
  3. Using RColorBrewer with ggplot2
  4. Color-Blind Friendly Palettes
  5. Advanced: Customizing & Exporting Colors
  6. FAQs
  7. Related Tutorials

1. What is RColorBrewer?

RColorBrewer is an R package that brings the ColorBrewer palettes into R. These palettes were designed by cartographer Cynthia Brewer to be perceptually balanced, print-friendly, and accessible. Instead of choosing random hex codes, you can rely on curated sets tested for clarity and usability. This makes them ideal for academic graphics, business dashboards, and data storytelling. If you are also interested in annotation techniques, check out how to annotate clusters with circle or ellipse in ggplot2.

install.packages("RColorBrewer")
library(RColorBrewer)
display.brewer.all()

Compared to picking arbitrary hex codes, Brewer palettes give you tested color sets that remain legible in print, projection, and for many viewers with color-vision deficiencies.


display.brewer.all()

R ColorBrewer All Available Color Palettes
Sequential palette “Blues” applied to population growth data with ggplot2.

2. Types of Color Palettes in RColorBrewer

RColorBrewer organizes its palettes into three families: sequential, diverging, and qualitative. Choosing the right palette ensures your data is interpreted correctly—sequential palettes emphasize magnitude, diverging palettes highlight deviations, and qualitative palettes distinguish categories. Below are examples of each type in action with ggplot2.

Sequential palettes

Sequential palettes are best for ordered data where values progress from low to high, such as population counts, temperatures, or sales volumes. These palettes use light-to-dark color schemes that naturally encode magnitude. For example, a bar chart of population growth becomes more intuitive when a sequential palette like Blues is applied. You can combine this with techniques like custom axis formatting to improve readability.


df  head()

df |>
  ggplot(aes(city, pop, fill=city)) +
  geom_col() +
  scale_fill_brewer(palette="Blues", guide="none")+
  labs(title="RColorBrewer: Sequential Palette Example")
ggsave("RColorBrewer_Sequential_Palette_Example.png")
RColorBrewer: Sequential Palette Example
RColorBrewer: Sequential Palette Example

Diverging palettes

Diverging palettes are designed for data that deviates around a meaningful center, such as profit vs. loss, test scores above and below average, or standardized z-scores. They use two contrasting hues with a neutral midpoint, making positive and negative differences stand out clearly. A heatmap of z-scores is a common example where the RdBu palette highlights above-average (red) and below-average (blue) values. If you want to extend this with shapes or highlights, check out how to highlight points in ggplot2.


library(palmerpenguins)
df_z  
  drop_na() |>
  group_by(species) |>
  summarize(across(where(is.numeric), mean)) |>
  pivot_longer(-species, 
               names_to="metric",
               values_to="value") |>
  group_by(metric) |>
  mutate(z=(value-mean(value))/sd(value)) |>
  ungroup()

df_z |> head()


species metric value z
Adelie	bill_length_mm	38.82397	-1.1468905	
Adelie	bill_depth_mm	18.34726	0.5585044	
Adelie	flipper_length_mm	190.10274	-0.7656791	
Adelie	body_mass_g	3706.16438	-0.5942492	
Adelie	year	2008.05479	0.4550641	
Chinstrap	bill_length_mm	48.83382	0.6895555	


df_z |>
  ggplot(aes(species, 
             metric,
             fill=z)) +
  geom_tile(color="white") +
  scale_fill_distiller(palette="RdBu",
                       direction=-1)
ggsave("RColorbrewer_diverging_palette_heatmap_example.png")

RColorBrewer diverging palette heatmap example
RColorBrewer diverging palette heatmap example

Qualitative palettes

Qualitative palettes are ideal for categorical data where the goal is to separate groups rather than encode magnitude. Each category is assigned a distinct color, making it easy to compare groups such as species, regions, or product types. A scatterplot of penguin species is a good example, where the Set2 palette ensures each species is visually distinct. For another approach to category visualization, explore adding text labels to ggplot2.


penguins |>
  ggplot( aes(bill_length_mm, 
             flipper_length_mm, 
             color=species)) +
  geom_point(size=2, 
             alpha=0.8, 
             na.rm=TRUE) +
  scale_color_brewer(palette="Set2")
ggsave("RColorbrewer_qualitative_palette_example.png")
RColorBrewer: Qualitative  Palette Example
RColorBrewer: Qualitative Palette Example

3. Using RColorBrewer with ggplot2

The RColorBrewer palettes work seamlessly with ggplot2. Depending on whether your variable is categorical or continuous, you will use different functions to apply palettes. This section shows the key functions, when to use them, and examples for each.

Data Type Function Palette Type Example Use
Categorical (discrete groups) scale_fill_brewer() / scale_color_brewer() Qualitative Boxplots, bar charts, stacked charts
Continuous (numeric values) scale_fill_distiller() / scale_color_distiller() Sequential or Diverging Heatmaps, scatterplots with gradients

Using scale_fill_brewer() for categorical groups

scale_fill_brewer() applies a qualitative palette to discrete categories. This is ideal for grouped bar charts, boxplots, or stacked charts where each category needs its own distinct color. In the example below, penguin species are assigned colors from the Set2 palette, making it easy to distinguish groups without implying any numerical order. Brewer’s qualitative palettes are designed to maximize contrast and readability across categories.


library(palmerpenguins)

penguins |>
  ggplot(aes(species, body_mass_g, fill = species)) +
  geom_boxplot() +
  scale_fill_brewer(palette = "Set2") +
  theme(legend.position="none")+
  labs(title = "Categorical groups with scale_fill_brewer",
       x = "Species", 
       y = "Body mass (g)") 
ggsave("RColorBrewer_scale_fill_brewer_example.png")
RColorBrewer: Categorical groups with scale_fill_brewer()
RColorBrewer: Categorical groups with scale_fill_brewer()

Using scale_color_distiller() for continuous values

scale_color_distiller() is designed for continuous variables, creating a smooth gradient from a sequential or diverging palette. It is particularly useful when mapping measurements such as temperature, counts, or body size to color in scatterplots or heatmaps. In the example below, penguin body mass is mapped to color using the YlGnBu palette, where lighter shades represent lighter penguins and darker shades indicate heavier penguins. This allows viewers to see both trends and outliers at a glance.


penguins |>
  ggplot(aes(bill_length_mm, 
             flipper_length_mm, 
             color = body_mass_g)) +
  geom_point(size = 2, 
             alpha = 0.8, 
             na.rm = TRUE) +
  scale_color_distiller(palette = "YlGnBu",
                        direction = 1) +
  labs(title = "Continuous mapping with scale_color_distiller",
       subtitle = "Body mass mapped to color with YlGnBu palette",
       x = "Bill length (mm)", 
       y = "Flipper length (mm)",
       color = "Body mass (g)") 
ggsave("RColorBrewer_continuous_mapping_scale_color_distiller.png")
RColorBrewer: Continuous mapping with scale_color_distiller()
RColorBrewer: Continuous mapping with scale_color_distiller()

4. Color-Blind Friendly Palettes

About 8% of men and 0.5% of women live with some form of color vision deficiency, which means charts using poor color choices can be misleading or unreadable for many viewers. The RColorBrewer package helps solve this by marking which palettes are safe for color-blind audiences.

Using these palettes improves accessibility, ensures fair interpretation of your data, and makes your visualizations more inclusive. You can check for safe palettes directly in R and visualize them before applying to your plots.


# List only color-blind friendly palettes

brewer.pal.info |>
  filter(colorblind == TRUE) |> 
  head()
##        maxcolors category colorblind
## BrBG          11      div       TRUE
## PiYG          11      div       TRUE
## PRGn          11      div       TRUE
## PuOr          11      div       TRUE
## RdBu          11      div       TRUE
## RdYlBu        11      div       TRUE
# Show all color-blind safe palettes visually
display.brewer.all(colorblindFriendly = TRUE)

# Show all color-blind safe palettes visually
display.brewer.all(colorblindFriendly = TRUE)
RColorBrewer color blind friendly palettes
RColorBrewer color blind friendly palettes

Sequential blue and purple gradients, diverging blue–orange schemes, and qualitative sets such as Set2 or Dark2 are generally recommended. These palettes remain distinct even when certain colors are harder to perceive. The example below shows a side-by-side comparison between a non-friendly palette and a color-blind friendly palette in ggplot2 boxplots, highlighting why thoughtful palette choice matters.

Example: Comparing non-friendly vs. friendly palettes

When visualizing categorical groups, using a non-friendly palette can cause confusion because some colors may appear indistinguishable to people with red–green color blindness. In contrast, a color-blind friendly palette ensures that each group remains distinct and interpretable. The following example compares two boxplots of penguin body mass by species: one styled with the Paired palette (not safe), and one styled with the Set2 palette (safe). Notice how the Set2 version is easier to interpret and more accessible.


library(tidyverse)
library(palmerpenguins)
# Non-friendly qualitative palette (Paired)
p_non 
  ggplot(aes(species, 
             body_mass_g, 
             fill = species)) +
  geom_boxplot() +
  scale_fill_brewer(palette = "Paired") +
  labs(title = "Non-friendly palette (Paired)",
       x = "Species", 
       y = "Body mass (g)") +
  theme(legend.position = "none")
# Save plot
ggsave("rcolorbrewer-nonfriendly.png", p_non, width=6, height=4, dpi=200)
RColorBrewer Non-Color Blind Friendly Palette Example
RColorBrewer Non-Color Blind Friendly Palette Example

# Friendly qualitative palette (Set2)
p_friendly 
  ggplot(aes(species, 
             body_mass_g, 
             fill = species)) +
  geom_boxplot() +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "Color-blind friendly palette (Set2)",
       x = "Species", y = "Body mass (g)") +
  theme(legend.position = "none")
ggsave("rcolorbrewer-friendly.png", p_friendly, width=6, height=4, dpi=200)
RColorBrewer Color Blind Friendly Palette Example
RColorBrewer Color Blind Friendly Palette Example

5. Practical Tips for Choosing Palettes

RColorBrewer offers many options, but choosing the right palette depends on your data type and the story you want to tell. Below are practical guidelines with references to examples shown earlier in this guide, so you can quickly apply the right palette in your own visualizations.

Use sequential palettes for ordered data

Sequential palettes are best when your values move in one direction, such as counts, percentages, or continuous measures like temperature. They use light-to-dark shades that make it easy to spot high and low values. See sequential palette example above.

Sequential palette example using Blues in ggplot2

Use diverging palettes for deviations around a midpoint

Diverging palettes are ideal for showing values above and below a central point such as zero, an average, or a target. They use two contrasting hues with a neutral center, making deviations stand out clearly. See diverging palette example above.

Diverging palette example using RdBu in ggplot2

Use qualitative palettes for categories

Qualitative palettes are designed for unordered categories such as species, product types, or regions. Each group gets a distinct color, making it easy to compare categories without implying order. See qualitative palette example above.

Qualitative palette example using Set2 in ggplot2

Limit the number of categories

Most qualitative palettes support up to 8–12 colors. Adding more categories makes it harder to distinguish groups and reduces clarity. If you have many categories, consider grouping them, filtering for key values, or using faceting instead of forcing all into a single chart.

Avoid misleading color choices

Always align palette type with data type. For example, avoid using sequential palettes for categories, since they suggest order where none exists. Be cautious with red–green contrasts, as they are problematic for many color-blind viewers. Choose palettes flagged as color-blind friendly, such as Set2, Dark2, or safe sequential schemes, to keep your charts accessible.

Quick Reference: RColorBrewer Palette Choice in ggplot2

Palette Type When to Use ggplot2 Function Recommended Palettes Example
Sequential Ordered values progressing low → high (counts, percentages, temps) scale_fill_distiller() / scale_color_distiller() Blues, Greens, Purples, YlGnBu See sequential example
Diverging Deviations around a center (0, mean, target) scale_fill_distiller() / scale_color_distiller() RdBu, RdYlBu, PuOr See diverging example
Qualitative Unordered categories (species, regions, groups) scale_fill_brewer() / scale_color_brewer() Set2, Dark2, Set3 See qualitative example

Accessibility tip: Whenever possible, prefer palettes flagged as color-blind friendly, such as Set2, Dark2, many blue/purple sequentials, and blue–orange diverging schemes. You can quickly check safe options with brewer.pal.info or preview them using display.brewer.all(colorblindFriendly = TRUE). See accessibility guidance above.

Related posts:

How to Make Heatmap with ggplot2?How To Make Simple Heatmaps with ggplot2 in R? Stacked Barplots Side By Side with ggplot2 in RHow to Make Horizontal Stacked Barplots with ggplot2 in R? Scatter Plot R: Fill color by variableHow To Color Scatter Plot by Variable in R with ggplot2? How to Make Barplots with Error bars in R?How To Make Barplots with Error bars in ggplot2?

Filed Under: Color Palettes RColorBrew, R Tagged With: R

Primary Sidebar

Python & R Viz Hubs

  • Seaborn Guide & Cookbook
  • ggplot2 Guide & Cookbook
  • Matplotlib Guide & Cookbook
  • Confusion Matrix Calculator
  • Visualizing Activation Functions
  • Visualizing Dropout
  • Visualizing Loss Functions

Buy Me a Coffee

Copyright © 2026 · Daily Dish Pro on Genesis Framework · WordPress · Log in

Go to mobile version