2
votes

A pressing deadline means I've run out of time to stumble through this so apologies if it's been asked before.

I can't figure out how to (or if it is possible) to apply a slightly extended RColorBrewer colour palette to factor data in a ggplot line plot.

I have the following 3 variable data (lots of datapoints so I wont paste it all here), in an already-melted dataframe.

> head(spec.melt)
  Temperature Wavelength CD_Intensity
1          20        260    0.0807910
2          25        260    0.3019320
3          30        260    0.1363325
4          35        260    0.0000000
5          40        260    0.1354045
6          45        260    0.0000000
... # tail(spec.melt)
     Temperature Wavelength CD_Intensity
5635          65        185    0.2499200
5636          70        185    2.5051893
5637          75        185    0.4399785
5638          80        185    4.4368350
5639          85        185    2.0015100
5640          90        185    2.8696540

For each Temperature (25-90), a wavelength scan (260nm-190nm) was conducted, gathering CD Intensity, Thus there are 15 spectra of 260-190nm measurements collapsed in this df.

I can plot this fine so far, and the default ggplot theme is applied. Since the series data will be temperature, I'd like to colour them using a theme which shows this (e.g. RColorBrewers "RdYlBu").

I have 15 temperatures though, and by default "RdYlBu" is an 11 colour spectrum.

Here's my code:

# Import spectrum data
spectrum.obj <- read.table(spectrum,
                           sep = ",",
                           header = TRUE,
                           row.names = 1,
                           check.names = FALSE)

spec.melt <- melt(t(spectrum.obj), value.name = "CD_Intensity", varnames=c("Temperature","Wavelength"))



# # Plot and customise spectrum space
spectrum.img <- ggplot(spec.melt, aes(x=Wavelength, y=CD_Intensity, group=factor(Temperature)))
spectrum.img <- spectrum.img + geom_line(aes(color=factor(Temperature)))
# Axis titles
spectrum.img <- spectrum.img + ylab("CD Intensity (mdeg)") +
                               xlab("Wavelength (nm)") + 
                                guide_legend(title="my awesome title")
# Make transparent
spectrum.img <- spectrum.img + theme_bw()
spectrum.img <- spectrum.img + theme(legend.position = "bottom",
                                     legend.title = element_text("test"),
                                     plot.background = element_blank(),
                                     panel.background = element_blank(),
                                     legend.background = element_blank())



spectrum.img

Currently, if I change geom_line(aes(color=factor(Temperature))) to anything else, it breaks.

For bonus points, if anyone can tell me why legend.title isn't producing anything that would be great too, as currently, I'm stuck with "factor(Temperature)"

EDIT: Here's the raw data (in CSV form) https://pastebin.com/ZwtvU8Kq

2

2 Answers

2
votes

I would particularly advise against RdYlBu since it's a diverging palette. This biases you towards the high and low end of your scale. Instead try a perceptually uniform palette like YlOrRd or even better, one from the viridis package.

You can use these in your code by keeping colour = Temperature and group = Temperature (not factor(Temperature)). Then use scale_color_distiller(palette = "YrOrRd") or scale_color_viridis().

enter image description here


enter image description here


enter image description here

Finally, to fix your labels, it's much easier to use something like:

ggplot(...) + ... + 
  labs(x = "Wavelength (nm)",
       y = "CD Intensity (mdeg)",
       color = "Temperature",
       title = "My title")
2
votes

This doesn't answer your exact question, but if all you are looking for is a gradient between three colours, you can generate a manual scale:

colours <- colorRampPalette(c("blue", "yellow", "red"))(15)

You could tinker with the exact versions of the colours (darkred vs red) to adjust this scale a little bit. Then, just use the usual:

scale_color_manual("Awesome title", 
                   labels = as.character(seq(20, 90, length.out = 15)),                  
                   values = colours)

I can't run your code without data, but this should fix your legend title if you get rid of your other legend title code.

Update:

The following works with your code (ggplot2 2.2.1):

library(reshape)
library(ggplot2)

# Import spectrum data
spectrum.obj <- read.table('test.csv',
                           sep = ",",
                           header = TRUE,
                           row.names = 1,
                           check.names = FALSE)

spec.melt <- melt(t(spectrum.obj), varnames=c("Temperature","Wavelength"))

# # Plot and customise spectrum space
spectrum.img <- ggplot(spec.melt, aes(x=Wavelength, y=value, group=factor(Temperature)))
spectrum.img <- spectrum.img + geom_line(aes(color=factor(Temperature)))

# Changing colour
colours <- colorRampPalette(c("blue", "yellow", "red"))(15) 
spectrum.img <- spectrum.img + 
                scale_color_manual("Awesome title", 
                                   labels = as.character(seq(20, 90, length.out = 15)),                  
                                   values = colours)

# Axis titles
spectrum.img <- spectrum.img + ylab("CD Intensity (mdeg)") +
                               xlab("Wavelength (nm)")

# Make transparent
spectrum.img <- spectrum.img + theme_bw()
spectrum.img <- spectrum.img + theme(legend.position = "bottom",
                                     plot.background = element_blank(),
                                     panel.background = element_blank(),
                                     legend.background = element_blank())