Change the Default Colour Palette in Ggplot

Change the default colour palette in ggplot

@baptiste pointed me to a message board post that mentions the function set_default_scale which can be used to set a default palette. The following solution only works with old versions of ggplot2, though.

First we need a function that produces colour names or codes. I called mine magazine.colours:

magazine.colours <- function(n, set=NULL) {
set <- match.arg(set, c('1', '2'))
palette <- c("red4", "darkslategray3", "dodgerblue1", "darkcyan",
"gray79", "black", "skyblue2", "dodgerblue4",
"purple4", "maroon", "chocolate1", "bisque3", "bisque",
"seagreen4", "lightgreen", "skyblue4", "mediumpurple3",
"palevioletred1", "lightsalmon4", "darkgoldenrod1")
if (set == 2)
palette <- rev(palette)
if (n > length(palette))
warning('generated palette has duplicated colours')
rep(palette, length.out=n)
}

(It accepts an optional set argument just to show that you are not restricted to a single palette.) Ok, now we create a "scale", which I called magazine. It's based on ggplot's brewer scale and the code is pretty ugly:

ScaleMagazine <- proto(ScaleColour, expr={
objname <- 'magazine'
new <- function(., name=NULL, set=NULL, na.colour='yellowgreen',
limits=NULL, breaks = NULL, labels=NULL,
formatter = identity, variable, legend = TRUE) {
b_and_l <- check_breaks_and_labels(breaks, labels)
.$proto(name=name, set=set, .input=variable, .output=variable,
.labels = b_and_l$labels, breaks = b_and_l$breaks,
limits= limits, formatter = formatter, legend = legend,
na.colour = na.colour)
}
output_set <- function(.) {
missing <- is.na(.$input_set())
n <- sum(!missing)
palette <- magazine.colours(n, .$set)
missing_colour(palette, missing, .$na.colour)
}
max_levels <- function(.) Inf
})
scale_colour_magazine <- ScaleMagazine$build_accessor(list(variable = '"colour"'))
scale_fill_magazine <- ScaleMagazine$build_accessor(list(variable = '"fill"'))

The important thing here is to define output_set which is the function that ggplot calls to get the colour names/codes. Also, if you need extra arguments, those must be included in new and later can be accessed as .$argument_name. In the example above, output_set simply calls magazine.colours.

Now, check the new scale does actually work:

qplot(mpg, wt, data=mtcars, shape=21,
colour=factor(carb), fill=factor(carb)) +
scale_colour_magazine(set='1') +
scale_fill_magazine(set='1')

To make it the default, simply use set_default_scale.

set_default_scale("colour", "discrete", "magazine") 
set_default_scale("fill", "discrete", "magazine")

And that'll be it.

> qplot(mpg, wt, data=mtcars, colour=factor(carb), fill=factor(carb))

plot showing the new palette

How to change default color scheme in ggplot2?

It looks like

options(ggplot2.continuous.colour="viridis")

will do what you want (i.e. ggplot will look for a colour scale called

scale_colour_whatever

where whatever is the argument passed to ggplot2.continuous.colourviridis in the above example).

library(ggplot2)
opts <- options(ggplot2.continuous.colour="viridis")
dd <- data.frame(x=1:20,y=1:20,z=1:20)

ggplot(dd,aes(x,y,colour=z))+geom_point(size=5)
options(oldopts) ## reset previous option settings

For discrete scales, the answer to this question (redefine the scale_colour_discrete function with your chosen defaults) seems to work well:

scale_colour_discrete <- function(...) {
scale_colour_brewer(..., palette="Set1")
}

Emulate ggplot2 default color palette

It is just equally spaced hues around the color wheel, starting from 15:

gg_color_hue <- function(n) {
hues = seq(15, 375, length = n + 1)
hcl(h = hues, l = 65, c = 100)[1:n]
}

For example:

n = 4
cols = gg_color_hue(n)

dev.new(width = 4, height = 4)
plot(1:n, pch = 16, cex = 2, col = cols)

Sample Image

How do I adapt my ggplot code in order to change the default colours used in the chart produced?

This is quite a general question, so there are quite a few answers, here. Generally, you change the colors used in the plot via one of the scale_*_** functions, where * is the aesthetic (color, fill, etc), and ** is the type or method for creating the scale. Some of these include:

  • manual for manually defining stuff
  • brewer to use one of the predefined Brewer color palettes
  • discrete for discrete scales
  • gradient, gradient2 or gradientn to define color gradients (you give some set number of colors and a gradient is created to apply to a continuous variable for the aesthetic).
  • viridis to use the viridis scales. There are discrete and continuous versions here, so you typically need to specify
  • and many others... like distiller, fermenter, and various others that come with RColorBrewer.

Here's some examples below to get you started. Here's a default plot:

p <- ggplot(mtcars, aes(x=factor(carb), y=mpg)) + geom_col(aes(fill=factor(carb)))
p

Sample Image

Example applying one of the Brewer scales:

p + scale_fill_brewer(palette='Set1')

Sample Image

Example using a viridis scale:

p + scale_fill_viridis_d()

Sample Image

Example using a manually-defined scale: Note here you specify using scale_fill_manual(values=...). The values= argument must be sent a vector or list of colors which are at least the same number as the number of levels for your variable assigned to the fill= aesthetic. You can also pass a named vector to explicitly define which color is applied to individual factor levels. Here I'm just showing you the lovely colors of the rainbow:

p + scale_fill_manual(values=rainbow(6))

Sample Image

How to reverse the default color palette for ggplot2

The default color palette ggplot uses is scale_color_hue.

ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species))+geom_point()

is equivalent to

ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species)) +
geom_point() + scale_color_hue(direction = 1)

direction = -1 does reverse the colors. But then you need to adjust the starting point in the hue wheel, in order to get the same three colors in reversed order.

ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species))+geom_point()+
scale_color_hue(direction = -1, h.start=90)

Each color moves the hue pointer 30 degrees. So we set the starting point at 90.

hue wheel

BTW, in order to let scale_colour_brewer work for categorical variables, you need to set type = 'qual':

ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species))+geom_point()+
scale_color_brewer(type = 'qual', palette = 'Dark2')

Overriding default colours in a ggplot diagram

Note: The convention on SO is that "answers" are reserved for reproducible code that demonstrates a solution. Anything less (like a suggestion) belongs in a comment. This is why it is so essential that questioners provide their data as part of the question; otherwise we have to make some up for you, which most people are (justifiably) unwilling to do.

The answer you asked for is below, but before getting into that you should be aware that ggplot's default color scheme is carefully chosen, so you should only change it if there is a good reason. The problem is that human evolution has caused certain colors (like red) to get a perceptual boost relative to other colors. So if you have a red curve and a black curve, the red curve leaves a stronger "impression". This fact is used extensively in certain fields (like advertising) to psychologically manipulate the viewer, but it has no place in scientific data visualization. The ggplot defaults, which are based on the HCL color system (which in turn is based on the Munsell color system), try to achieve two objectives: to create a color palette where each color is maximally distinguishable from all the other colors, and to even out the relative perceptual impact. There is a fairly technical discussion of this topic here, and some nice examples here.

Bottom line: don't change the colors unless you have a really good reason to do so.

Having said all that, the simple answer to your question is to use scale_color_manual(...), as below:

# all this to set up the example - you have this already
set.seed(1) # for reproducible example
x <- rep(c(1,2,4,8,11,14), each=5)
df1 <- data.frame(Day=x,Control=125*(1-exp(-x/5))+rnorm(30,sd=25),Supp="N")
df2 <- data.frame(Day=x,Control=90*(1-exp(-x/3))+rnorm(30,sd=25),Supp="C")
plasma1 <- aggregate(Control~Day+Supp,rbind(df2, df1), FUN=function(x)c(Control=mean(x),SEMcontrol=sd(x)/sqrt(length(x))))
plasma1 <- data.frame(plasma1[,1:2],plasma1[[3]])

# you start here
library(ggplot2)
ggp <- ggplot(plasma1, aes(x=Day, y=Control, color=Supp))+
geom_point(size=3, shape=21)+
geom_line(linetype="dashed")+
geom_errorbar(aes(ymax=Control+SEMcontrol, ymin=Control-SEMcontrol), width=0.3)+
theme_bw()+theme(panel.grid=element_blank())
ggp + scale_color_manual(values=c(C="red",N="black"))

Which produces this:

Sample Image

As mentioned in one of the comments, you could also use one of the Brewer Palettes developed by Prof. Cynthia Brewer at Penn State. These were originally intended for cartographic applications, but have become widely used generally in scientific visualization.

ggp + scale_color_brewer(palette="Set1")

Sample Image



Related Topics



Leave a reply



Submit