Picking Pretty Plot Palates




The default colors for ggplot2 are pretty lovely, in my opinion, but sometimes you want more control. Or maybe you’re just procrastinating some less appealing work. Whatever the reason, sometimes you find yourself wanting to test new color palates for your plots. Here’s an easy way to do that. I’m using color brewer, which is an awesome color tool for all of your programming needs, not just R. It includes some palates that are specifically designed to be colorblind safe, printer friendly, and/or photocopier friendly.

library(ggplot2)
library(RColorBrewer)

# pick a palette
display.brewer.all()

plot of chunk unnamed-chunk-1

# you can call them by name 
colors <- brewer.pal(9,"Spectral") 
colors <- c(colors[1:3], colors[7:9]) #take just the 6 colors from the two ends (they're brighter)
# how to check out a color palette
n <- 6 # the number of colors to plot
pie(rep(1,n), col=colors, main="Well, that's lovely!")

plot of chunk unnamed-chunk-2

pie(rep(1,n), col=brewer.pal(11,"BrBG")[1:6], main="Mmm toasty")

plot of chunk unnamed-chunk-2

pie(rep(1,n), col=brewer.pal(6,"Blues"), main="Let it go, let it go!")

plot of chunk unnamed-chunk-2

Here’s how R is saving your colors (these are the ones I saved from Spectral):

colors
## [1] "#D53E4F" "#F46D43" "#FDAE61" "#ABDDA4" "#66C2A5" "#3288BD"

How to use your pretty new palate in ggplot2:

# making up some very plausible data predicting attractiveness from your R expertise and your hair style
n <- 6*50
R.Skillz <- runif(n, min=0,max=12) 
Hair.Style <- rep(c("bald", "french bob", "rapunzel", "mohawk", "clown hair", "whale spout"), n/6)
Attractiveness <- abs(ifelse(Hair.Style=="whale spout", .8*R.Skillz, 
                         ifelse(Hair.Style=="clown hair", R.Skillz - .1*R.Skillz^2, 
                                ifelse(Hair.Style=="bald", -.1*(R.Skillz-6)^2+5, 
                                       ifelse(Hair.Style=="mohawk", .3*R.Skillz + 3,
                                              ifelse(Hair.Style=="french bob", .2*R.Skillz-1,
                                         .2*R.Skillz + 3))))) + rnorm(n, sd=.5))
df <- data.frame(Attractiveness = Attractiveness, R.Skillz=R.Skillz, Hair.Style=Hair.Style)

You need a different argument depending on if you want to apply your colors to points/lines or filled-in stuff like bars.

# use scale_fill_manual() for filling in bars
library(dplyr)
means <- summarise(group_by(df, Hair.Style), mean=mean(Attractiveness), var=var(Attractiveness), n=n(), se=sqrt(var/n), ci=se*qt(.975, df=n-1))

ggplot(means, aes(y=mean, x=Hair.Style))+
  geom_bar(stat="identity", aes(fill=Hair.Style)) +
  geom_errorbar(aes(ymin=mean-ci, ymax=mean+ci),
                  width=.2,                    # Width of the error bars
                  position=position_dodge(.9)) +
  labs(y="Attractiveness", x="Hair Style") +
  theme(axis.text.x = element_text(angle = -45, hjust = 0), legend.position="none") +
  scale_fill_manual(values=colors)

plot of chunk unnamed-chunk-5

# use scale_color_manual() for points and lines
ggplot(df, aes(y=Attractiveness, x=R.Skillz, color=Hair.Style))+
  geom_point() + 
  scale_color_manual(values=colors) 

plot of chunk unnamed-chunk-5

# Note that stat_smooth needs "fill", so if you want to control color for both points and the error on stat_smooth, you need scale_color_manual() and scale_fill_manual()
ggplot(df, aes(y=Attractiveness, x=R.Skillz, color=Hair.Style))+
  geom_point() + 
  stat_smooth(aes(fill = Hair.Style)) +
  scale_color_manual(values=colors) +
  scale_fill_manual(values=colors)

plot of chunk unnamed-chunk-5



Comments are closed.