Written and maintained by CASRAI Editorial Board
Last updated
To change colours in a ggplot2 figure, map a variable to the colour or fill aesthetic and then add a scale function that controls the palette. For a categorical variable use scale_colour_brewer(), scale_colour_viridis_d() or scale_colour_manual(); for a continuous variable use scale_colour_viridis_c() or scale_colour_distiller(). This guide organises the ggplot colour palette options by the type of variable you are plotting, lists the exact palette names the official reference documents, and explains the one rule about scale_colour_manual() that causes most wrong-colour bugs.
What it is used for in research
Colour in a research figure usually encodes a grouping (treatment arm, species, site) or a measured quantity (expression level, concentration). ggplot2 handles both through scales: the aesthetic mapping says which variable is shown by colour, and the scale decides which colours are used. If you add no scale, ggplot2 applies its default discrete scale, scale_colour_hue(), which maps each level to an evenly spaced hue on the colour wheel. The ggplot2 reference states that this scale does not generate colour-blind safe palettes, so for figures that will be published it is worth choosing a palette deliberately. The same scale logic applies in the chart types covered in our guides to ggplots in R, scatterplots in R, box plots in R and heatmaps in R.
Choose a colour scale by variable type
The ggplot2 reference documents three families of ready-made scales plus a manual option. Pick the row that matches your variable.
| Variable type | Brewer family | Viridis family | Manual |
|---|---|---|---|
| Discrete (categories) | scale_colour_brewer() |
scale_colour_viridis_d() |
scale_colour_manual() |
| Continuous | scale_colour_distiller() |
scale_colour_viridis_c() |
not applicable |
| Binned (continuous values cut into classes) | scale_colour_fermenter() |
scale_colour_viridis_b() |
not applicable |
Each function has a fill twin (for example scale_fill_brewer()). Use the colour version for points, lines and outlines, and the fill version for bars, boxes, tiles and polygon interiors. The ggplot2 reference describes the brewer scales as designed and tested on discrete data and not designed to be extended to continuous data, which is why scale_colour_distiller() and scale_colour_fermenter() exist as the continuous and binned counterparts.
Install or access (official source only)
ggplot2 is part of the tidyverse and is distributed through CRAN. Install and load it in R with:
install.packages("ggplot2")
library(ggplot2)
The scale functions below ship with ggplot2. The official reference for every function named in this guide is at ggplot2.tidyverse.org/reference, listed under Sources.
Step-by-step: colour a plot in ggplot2
The examples use the built-in mtcars data set, the same one used in the ggplot2 reference examples.
1. Map a variable to colour or fill
p <- ggplot(mtcars, aes(mpg, wt)) +
geom_point(aes(colour = factor(cyl)))
p
Wrapping cyl in factor() makes it discrete, so ggplot2 uses a discrete scale (the default hue scale here). Mapping a numeric column without factor() would produce a continuous colour bar instead.
2. ggplot color palettes: ColorBrewer with scale_colour_brewer()
p + scale_colour_brewer(type = "qual", palette = "Dark2")
The signature is scale_colour_brewer(name = waiver(), ..., type = "seq", palette = 1, direction = 1, aesthetics = "colour"). type is one of "seq", "div" or "qual", and palette accepts a palette name or a numeric index. The documented palette names are:
- Sequential (
seq): Blues, BuGn, BuPu, GnBu, Greens, Greys, Oranges, OrRd, PuBu, PuBuGn, PuRd, Purples, RdPu, Reds, YlGn, YlGnBu, YlOrBr, YlOrRd. - Diverging (
div): BrBG, PiYG, PRGn, PuOr, RdBu, RdGy, RdYlBu, RdYlGn, Spectral. - Qualitative (
qual): Accent, Dark2, Paired, Pastel1, Pastel2, Set1, Set2, Set3.
Qualitative palettes suit unordered categories; sequential and diverging palettes suit ordered levels. For bars or boxes, use the fill twin: scale_fill_brewer(palette = "Set1").
3. ggplot colors palette for colour-blind readers: viridis
p + scale_colour_viridis_d()
p + scale_colour_viridis_d(option = "plasma")
The discrete signature is scale_colour_viridis_d(name, ..., alpha = 1, begin = 0, end = 1, direction = 1, option = "D", aesthetics = "colour"). The option argument selects the palette by name or letter:
| Letter | Name |
|---|---|
| A | magma |
| B | inferno |
| C | plasma |
| D (default) | viridis |
| E | cividis |
| F | rocket |
| G | mako |
| H | turbo |
The ggplot2 reference says the viridis scales are also designed to be perceived by viewers with common forms of colour blindness, and that they are perceptually uniform, including in black and white. The statement covers the viridis family as a whole, so check a figure yourself if you rely on one specific option. The default hue scale, by contrast, is documented as not colour-blind safe.
4. Set exact colours with scale_colour_manual()
cols <- c("8" = "red", "4" = "blue", "6" = "darkgreen", "10" = "orange")
p + scale_colour_manual(values = cols)
The ggplot2 reference states that unnamed values are matched in order (usually alphabetical) with the limits of the scale, or with breaks if provided, and its own example comments that it is recommended to use a named vector, as above. This is the usual source of the “wrong colour on the wrong group” bug: with an unnamed vector the first colour goes to the alphabetically first level, not to the group you had in mind. Naming each value pins colour to level regardless of order. Further arguments from the same reference page:
scale_colour_manual(values = cols, aesthetics = c("colour", "fill"))applies one set of colours to both aesthetics.breaks = c("4", "6", "8")controls which levels appear in the legend and in what order, andlabels = c("four", "six", "eight")renames them.limits = c("4", "8")restricts the scale to those levels; data that do not match are drawn inna.value(default"grey50").
5. Continuous and binned variables
ggplot(mtcars, aes(mpg, wt, colour = hp)) +
geom_point() +
scale_colour_viridis_c(option = "plasma")
ggplot(mtcars, aes(mpg, wt, colour = hp)) +
geom_point() +
scale_colour_distiller(palette = "Blues")
ggplot(mtcars, aes(mpg, wt, colour = hp)) +
geom_point() +
scale_colour_fermenter(palette = "Blues")
scale_colour_viridis_c() adds values, space = "Lab", na.value = "grey50" and guide = "colourbar". scale_colour_distiller() takes the brewer type and palette arguments with direction = -1 by default, and scale_colour_fermenter() produces a binned scale with guide = "coloursteps". The binned viridis version is scale_colour_viridis_b().
Output and how to read it
A continuous scale draws a colour bar legend ("colourbar"); a binned scale draws stepped legend classes ("coloursteps"); a discrete scale draws one key per level. Read a discrete legend as a lookup from level to colour, and a sequential or viridis bar as ordered low-to-high. With diverging brewer palettes the two ends are two directions away from a neutral midpoint, which suits a variable with a meaningful centre value. Any observation drawn in grey50 is a missing or unmatched value, not a real category.
Troubleshooting
Colours are attached to the wrong groups
You are probably passing an unnamed vector to values. Use a named vector as shown in step 4, so matching does not depend on alphabetical level order.
Some points are grey
Grey50 is the default na.value in the manual, hue, continuous viridis and distiller scales. It appears for missing values and for levels outside limits or not matched by your named vector. Check that the names in your vector match the factor levels exactly, including how numbers are written as text.
The legend order or labels are wrong
Set breaks for order and labels for display text inside the scale function. The name argument sets the legend title; for scale_colour_manual() it is passed through ....
A brewer scale will not work on a continuous variable
Brewer scales are for discrete data. Use scale_colour_distiller() (continuous) or scale_colour_fermenter() (binned), or a viridis _c or _b scale.
Colour has no visible effect on bars
Bars and boxes are filled areas. Map fill and use a scale_fill_* function; colour only changes the outline.
Free alternatives (table)
Everything above is free, open-source ggplot2. Within it, these are the documented options for choosing colours:
| Option | Best for | Documented caveat |
|---|---|---|
Default scale_colour_hue() |
Quick exploratory plots with discrete groups | Does not generate colour-blind safe palettes |
| Brewer scales | Discrete data, with qualitative, sequential or diverging palettes | Not designed to be extended to continuous data |
| Viridis scales (A to H) | Discrete, continuous or binned data | Designed to be perceived under common forms of colour blindness |
| Manual scales | Fixed colours that must match across figures | Unnamed values are matched in order with scale limits or breaks |
If you need interactive figures instead of static ones, see our guide to plotly in R; the browsing hub for statistical tools is the research tools pillar.
FAQ
How do I change the colours in ggplot?
Map a variable to colour or fill inside aes(), then add a scale: scale_colour_brewer(), scale_colour_viridis_d() or scale_colour_manual() for categories, and scale_colour_viridis_c() or scale_colour_distiller() for continuous values.
What is the difference between ggplot color palettes and a colour scale?
A palette is the set of colours (for example Dark2 or plasma). The scale function is what applies that palette to a mapped variable. You choose the palette through arguments such as palette or option.
What is the default colour palette in ggplot2?
For discrete variables it is scale_colour_hue(), which maps each level to an evenly spaced hue on the colour wheel.
Which ggplot colour palette is colour-blind friendly?
The viridis scales are documented as designed to be perceived by viewers with common forms of colour blindness. The default hue scale is documented as not colour-blind safe.
How do I use my own colours?
Use scale_colour_manual() with a named vector so each colour is tied to a level.
Sources (official docs)
Checked 2026-10-29.
- ggplot2 reference: scale_brewer (ColorBrewer scales) – https://ggplot2.tidyverse.org/reference/scale_brewer.html
- ggplot2 reference: scale_viridis – https://ggplot2.tidyverse.org/reference/scale_viridis.html
- ggplot2 reference: scale_manual – https://ggplot2.tidyverse.org/reference/scale_manual.html
- ggplot2 reference: scale_hue – https://ggplot2.tidyverse.org/reference/scale_hue.html








