1
votes

How can I add a second legend for the shape aesthetics in ggplot?

The chart shows different start types (shape), different processes (color), and different end types (shape again). Currently, I am only able to display two legends: one for the color and one for the shape (which merges start.type and end.tpye). Any help on how to get the separate third legend (for the end.type)? Introducing linetype as an additional aesthetics is not an option. Many thanks.

id <- c("1","2","3")
start.date <- c("01/01/2010","05/05/2004","01/08/2006")
end.date <- c("31/12/2012","05/05/2007","01/09/2009")
start.type <- c("x1","x2","x3")
end.type <- c("y1","y2","y3")
process.type <- c("p1","p2","p3")
u <- data.frame(id,start.date, end.date,start.type,end.type,process.type)

u.plot <- ggplot(u)+
  geom_segment(aes(color=process.type, x=start.date, xend=end.date, y=id, yend=id), size=1)+
  geom_point(aes(shape=start.type, x=start.date, y=id), size=3)+
  geom_point(aes(shape=end.type, x=end.date, y=id), size=3)

plot(u.plot)

enter image description here

1
Standard ggplot only allows one legend per aesthetic. If you want to, you're going to have to hack it heavily. Is that something you want to do? It would probably be easier to edit it after the fact in a graphics program to split part the legend. It depends on how important this is to you.MrFlick
i was already afraid that this would be the case. quite surprised that there isn't a standard way for this. Problem is this (a similar) code runs in a loop over numerous dataframes. but thanks anyway.zoowalk

1 Answers

4
votes

enter image description here

editing the legend is likely to be painful and easily broken, but if you must try here's a quick and dirty way

require(gtable)
g = ggplotGrob(u.plot) # calls ggplot_build and ggplot_gtable
a = g$grobs[[8]][["grobs"]][[2]] # extract the legend (a gtable itself)
a = gtable_add_rows(a, unit(c(0.5,1),"line"), 6) # add two rows
new = editGrob(a[["grobs"]][[2]], label = "I'm in") # copy legend title with new text

a = gtable_add_grobs(a, new, 8, l=2, r=5) # place the new title
g$grobs[[8]][["grobs"]][[2]] = a # replace with new legend in the plot
grid.newpage()
grid.draw(g)