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))
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.colour
—viridis
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)
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 stuffbrewer
to use one of the predefined Brewer color palettesdiscrete
for discrete scalesgradient
,gradient2
orgradientn
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 withRColorBrewer
.
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
Example applying one of the Brewer scales:
p + scale_fill_brewer(palette='Set1')
Example using a viridis scale:
p + scale_fill_viridis_d()
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))
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.
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:
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")
Related Topics
Equivalent to Unix "Less" Command Within R Console
Should I Use a Data.Frame or a Matrix
How to Get Coefficients and Their Confidence Intervals in Mixed Effects Models
Convert Four Digit Year Values to Class Date
Setting Function Defaults R on a Project Specific Basis
Increase Resolution of Color Scale for Values Close to Zero
Select First Element of Nested List
Percentage on Y Lab in a Faceted Ggplot Barchart
How to Change Python Path in Reticulate
Pass Function Arguments to Both Dplyr and Ggplot
Create a Matrix of Scatterplots (Pairs() Equivalent) in Ggplot2
How to Change 'Maximum Upload Size Exceeded' Restriction in Shiny and Save User File Inputs
Download a File from Https Using Download.File()
How to Access the Help/Documentation .Rd Source Files in R
Python's Xrange Alternative for R or How to Loop Over Large Dataset Lazilly