Adding legend to geom_rect()

2,707 views
Skip to first unread message

Andrew

unread,
Dec 20, 2010, 7:29:59 PM12/20/10
to ggplot2

Please excuse the very simple request, but I'm new to ggplot and can't
find how to do this anywhere in the help or mailing list.

I have a geom_rect() plot showing two series of rectangles for each x
value:

df<-data.frame(x=c(1:5),y1=c(1:5),y2=c(8:12))
ggplot(df,aes(xmin=x,xmax=x+1))
+geom_rect(aes(ymin=y1,ymax=y1+1),fill="blue")
+geom_rect(aes(ymin=y2,ymax=y2+1), fill="red")

and would like to add a legend to this plot (eg. showing blue="series
1", red="series 2").

However, I can't do this simple task! I've tried many combinations of
possibilities, such as using the fill aesthetic [eg.
geom_rect(aes(..., fill="blue"))] and using scale_colour_manual, but
nothing I've tried works.

I'm sure this is down to my unfamiliarity with ggplot, but I've had to
give up. So any suggestions would be gratefully received!

Thanks very much.

Dennis Murphy

unread,
Dec 21, 2010, 5:48:21 PM12/21/10
to Andrew, ggplot2
Hi:

Try this:

df<-data.frame(x=c(1:5), y1=c(1:5),y2=c(8:12))
df2 <- melt(df, id = 'x')
names(df2) <- c('x', 'var', 'y')
ggplot(df2, aes(xmin=x,xmax=x+1)) +
  geom_rect(aes(ymin=y, ymax=y+1, fill= var)) +
  scale_fill_manual("", breaks = levels(df2$var),
                        values = c('blue', 'red'),
                        labels = c('Series 1', 'Series 2'))

(1) I melted the data to create a factor variable that can distinguish the two sets of y's
(2) The renamed factor is 'var', which you can map to fill in geom_rect()
(3) The empty double quote at the beginning of the scale call => no legend title. You can always fill one in.

Legends are very tricky for novices - I had a hard time with them for a few months. Scales are associated with mapped aesthetics (i.e., aesthetic elements that are set to variables inside aes() rather than constants). The scale_* functions let you manipulate aspects of the scale. Since the labels you want are different from the variable names and specific colors are desired, the most convenient thing to do in this case is to construct a manual scale, which provides the most control over features of the legend (and the most frustration :). The breaks are identified with the levels of the fill variable, the values = part associates colors with each level in breaks (in order), and labels = does the same for text labels. Also notice that the manual scale is associated with fill by name (scale_fill_manual).

On Mon, Dec 20, 2010 at 4:29 PM, Andrew <andre...@mac.com> wrote:

Please excuse the very simple request, but I'm new to ggplot and can't
find how to do this anywhere in the help or mailing list.

I have a geom_rect() plot showing two series of rectangles for each x
value:

df<-data.frame(x=c(1:5),y1=c(1:5),y2=c(8:12))
ggplot(df,aes(xmin=x,xmax=x+1))
+geom_rect(aes(ymin=y1,ymax=y1+1),fill="blue")
+geom_rect(aes(ymin=y2,ymax=y2+1), fill="red")

One other thing: in a mail message, put the + in a ggplot() call at the end of a line rather than the beginning. When someone copies and pastes that code into R as a block, the console inserts a + as a continuation character; another + immediately afterward throws an error.

and would like to add a legend to this plot (eg. showing blue="series
1", red="series 2").

However, I can't do this simple task! I've tried many combinations of
possibilities, such as using the fill aesthetic [eg.
geom_rect(aes(..., fill="blue"))] and using scale_colour_manual, but
nothing I've tried works.

I'm sure this is down to my unfamiliarity with ggplot, but I've had to
give up. So any suggestions would be gratefully received!

Thanks very much.

HTH,
Dennis

--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: http://gist.github.com/270442

To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2

Brandon Hurr

unread,
Dec 21, 2010, 3:05:08 PM12/21/10
to Andrew, ggplot2
I tried to follow Dennis's example here: 

But I couldn't get it to work either. Not sure why this is such a problem. 

ggplot(df,aes(xmin=x,xmax=x+1))+
geom_rect(aes(ymin=y1,ymax=y1+1),fill="blue")+
geom_rect(aes(ymin=y2,ymax=y2+1), fill="red")+ 
scale_fill_manual(name= "Legend", breaks=c("red", "blue"), 
      values= c("red", "blue"),
      labels=c("asdf", "jkl"))

Brandon

Andrew

unread,
Dec 21, 2010, 3:21:32 PM12/21/10
to ggplot2

Thanks very much to those who've helped. For the record, the command I
was missing is scale_fill:

df<-data.frame(x=c(1:5),y1=c(1:5),y2=c(8:12))
ggplot(df,aes(xmin=x,xmax=x+1)) +
geom_rect(aes(ymin=y1,ymax=y1+1, fill = "series 1")) +
geom_rect(aes(ymin=y2,ymax=y2+1, fill="series 2")) +
scale_fill_manual("Series",
values = c("series 1" = "blue", "series 2" = "red"))

Brandon Hurr

unread,
Dec 21, 2010, 3:43:47 PM12/21/10
to Andrew, ggplot2
It's always the little things... The "fill=..." needs to be in the aes() call. 

ggplot(df,aes(xmin=x,xmax=x+1))+
geom_rect(aes(ymin=y1,ymax=y1+1, fill="blue"))+
geom_rect(aes(ymin=y2,ymax=y2+1, fill="red"))+ 
scale_fill_manual(name= "Legend", breaks=c("red", "blue"), 
values= c("red", "blue"),
labels=c("asdf", "jkl"))

Does that fix it?

B
manual.scale.png

Andrew

unread,
Dec 21, 2010, 7:16:42 PM12/21/10
to ggplot2

That's very helpful - thanks! I hadn't found scale_fill_manual.
> > To unsubscribe: email ggplot2+u...@googlegroups.com<ggplot2%2Bunsu...@googlegroups.com>
> > More options:http://groups.google.com/group/ggplot2

Hadley Wickham

unread,
Dec 22, 2010, 8:39:05 PM12/22/10
to Dennis Murphy, Andrew, ggplot2
> Legends are very tricky for novices - I had a hard time with them for a few
> months. Scales are associated with mapped aesthetics (i.e., aesthetic
> elements that are set to variables inside aes() rather than constants). The
> scale_* functions let you manipulate aspects of the scale. Since the labels
> you want are different from the variable names and specific colors are
> desired, the most convenient thing to do in this case is to construct a
> manual scale, which provides the most control over features of the legend
> (and the most frustration :). The breaks are identified with the levels of
> the fill variable, the values = part associates colors with each level in
> breaks (in order), and labels = does the same for text labels. Also notice
> that the manual scale is associated with fill by name (scale_fill_manual).

My advice is to always think about the data - what variable are you
mapping to the fill colour? If that variable doesn't exist in your
data, it may be suggesting that you should reshape the data so that it
is.

Hadley

--
Assistant Professor / Dobelman Family Junior Chair
Department of Statistics / Rice University
http://had.co.nz/

Reply all
Reply to author
Forward
0 new messages