Harpal
Harpal

Reputation: 12577

ggplot2 legend colouring

I have a text table with 5 columns. I want to plot 4 of the columns as individual density plots on the same plot. I can achieve this as below: enter image description here

Code for the above plot:

library(ggplot2)
library(grid)

dat <- read.table(textConnection("
file        low        high       avg               lowest
102         4218.0     5437.0     4739.0            4723.0
103         4516.0     5765.0     5061.0            5036.0
104         4329.0     5554.0     4858.0            4838.0
107         4094.0     5261.0     4596.0            4578.0
108         4334.0     5569.0     4865.0            4846.0
109         4397.0     5596.0     4924.0            4896.0
110         4046.0     5257.0     4555.0            4547.0
"), header=TRUE)

x_low = dat$low
x_high = dat$high
x_avg = dat$avg
x_lowest = dat$lowest

plotter = ggplot() + geom_density(aes(x=x_low), colour="red", fill="red", alpha = .3, data=data.frame(dat$low))
plotter = plotter + geom_density(aes(x=x_high),colour="blue", fill="blue", alpha = .3, data=data.frame(dat$high))
plotter = plotter + geom_density(aes(x=x_avg), colour="green", fill="green", alpha = .3, data=data.frame(dat$avg))
plotter = plotter + geom_density(aes(x=x_lowest), colour="purple", fill="purple", alpha = .3, data=data.frame(dat$lowest))
plotter = plotter + xlim(c(2000,7000))
print(plotter)

I would now like to have a legend on the side of the plot. From my understanding I need to move the colour inside the brackets of aes

I do this as follows:

library(ggplot2)
library(grid)

dat <- read.table(textConnection("
file        low        high       avg               lowest
102         4218.0     5437.0     4739.0            4723.0
103         4516.0     5765.0     5061.0            5036.0
104         4329.0     5554.0     4858.0            4838.0
107         4094.0     5261.0     4596.0            4578.0
108         4334.0     5569.0     4865.0            4846.0
109         4397.0     5596.0     4924.0            4896.0
110         4046.0     5257.0     4555.0            4547.0
"), header=TRUE)

x_low = dat$low
x_high = dat$high
x_avg = dat$avg
x_lowest = dat$lowest

plotter = ggplot() + geom_density(aes(x=x_low, colour="red", fill="red"), alpha = .3, data=data.frame(dat$low))
plotter = plotter + geom_density(aes(x=x_high, colour="blue", fill="blue"), alpha = .3, data=data.frame(dat$high))
plotter = plotter + geom_density(aes(x=x_avg, colour="green", fill="green"), alpha = .3, data=data.frame(dat$avg))
plotter = plotter + geom_density(aes(x=x_lowest, colour="purple", fill="purple"), alpha = .3, data=data.frame(dat$lowest))

plotter = plotter + xlim(c(2000,7000))
print(plotter)

This outputs:

enter image description here

The colours of each plot are now wrong (when compared to the first plot) as well as the labelling in the legend.

How can I:

  1. Correct the colouring
  2. Remove the dark outline of each density plot
  3. Correct the legend

Upvotes: 0

Views: 2462

Answers (2)

Brian Diggs
Brian Diggs

Reputation: 58825

Dan M.'s answer is the idiomatic and most straightforward approach, but I wanted to show another which may have its place in some circumstances. You have the colour and fill scales which contain the colors that they should use; the scale you are looking for is the identity scale. Add the lines:

plotter = plotter + scale_fill_identity("", 
  labels=c("red"="low", "blue"="high", "green"="avg", "purple"="lowest"),
  guide="legend") 
plotter = plotter + scale_colour_identity("",
  labels=c("red"="low", "blue"="high", "green"="avg", "purple"="lowest"),
  guide="legend")

The "" argument gets rid of the legend title (if you want something there, replace this), labels give what each color should be labelled as. A named vector is needed to make sure that the matching between color and label is right (otherwise, the labels have to be given in alphabetical order by color). guide=TRUE draws a legend; by default, an identity scale doesn't have a legend. enter image description here

Upvotes: 1

Dan M.
Dan M.

Reputation: 1616

You can simplify this if you re-organize your data using melt from the reshape2 package. I think the following code will get you the correct legend, the fill colors you wanted, and get rid of the outline of the density plots:

dat.m <- melt(dat, id="file")
ggplot(dat.m, aes(value, fill=variable)) + geom_density(alpha = .3, color=NA) + scale_fill_manual(values=c("red", "blue", "green", "purple"))

Upvotes: 1

Related Questions