r - ggplot2: manually add a legend -
how can map any (unrelated) legend existing ggplot?
disclaimer: please don't hate me. know best way create legend 'ggplot2' map data right , 99% of time. here asking in general can give me legend want.
as example have plot looks this:
created code:
set.seed(42) temp1 = cbind.data.frame(begin = rnorm(10, 0, 1), end = rnorm(10, 2, 1), y1 = 1:10, y2 = 1:10, id = as.character(1:10)) temp2 = cbind.data.frame(x = 0:2, y = 1:3*2) temp3 = cbind.data.frame(x = seq(0.5, 1.5, 0.33)) temp = c() plot1 = ggplot(data = temp, aes(x = x)) + geom_vline(data = temp3, aes(xintercept = x), color = "red", linetype = "longdash") + geom_segment(data = temp1, aes(y = y1, yend = y2, x = begin, xend = end, color = id)) + geom_point(data = temp2, aes(x = x, y = y), shape = 4, size = 4) + scale_color_discrete(guide = f) plot1
and want add legend contains:
- a red, longdashed vertical line called "l1"
- a black, solid horizontal line called "l2"
- a green filled block called "l3"
ideally produce (pseudo-code ahead):
plot2 = plot1 + guide(elements = list(list(type = "line", color = "red", linetype = "longdash", direction = "vertical", label = "l1"), list(type = "line", label = "l2"), list(type = "rect", fill = "green", label = "l3"))
my best guess how approach create auxiliary pseudo-data temp
plotted/mapped somewhere invisible on plot , used create legend, not successful in getting plot me legend.
once more, idea how can add unrelated legend existing plot, i.e. without clever mapping of original data plot variables?
a legend can constructed scratch: use grid
construct elements of legend; use gtable
position elements within legend, , legend within plot. bit crude, gives general idea.
set.seed(42) temp1 = cbind.data.frame(begin = rnorm(10, 0, 1), end = rnorm(10, 2, 1), y1 = 1:10, y2 = 1:10, id = as.character(1:10)) temp2 = cbind.data.frame(x = 0:2, y = 1:3*2) temp3 = cbind.data.frame(x = seq(0.5, 1.5, 0.33)) temp = c() library(ggplot2) library(grid) library(gtable) plot1 = ggplot(data = temp, aes(x = x)) + geom_vline(data = temp3, aes(xintercept = x), color = "red", linetype = "longdash") + geom_segment(data = temp1, aes(y = y1, yend = y2, x = begin, xend = end, color = id)) + geom_point(data = temp2, aes(x = x, y = y), shape = 4, size = 4) + scale_color_discrete(guide = f) # construct 6 grobs - 3 symbols , 3 labels l1 = linesgrob(x = unit(c(.5, .5), "npc"), y = unit(c(.25, .75), "npc"), gp = gpar(col = "red", lty = "longdash")) l2 = linesgrob(x = unit(c(.25, .75), "npc"), y = unit(c(.5, .5), "npc")) l3 = rectgrob(height = .5, width = .5, gp = gpar(fill = "green", col = na)) t1 = textgrob("l1", x = .2, = "left") t2 = textgrob("l2", x = .2, = "left") t3 = textgrob("l3", x = .2, = "left") # construct gtable - 2 columns x 4 rows leg = gtable(width = unit(c(1,1), "cm"), height = unit(c(1,1,1,1), "cm")) leg = gtable_add_grob(leg, rectgrob(gp = gpar(fill = na, col = "black")), t=2,l=1,b=4,r=2) # place 6 grob table leg = gtable_add_grob(leg, l1, t=2, l=1) leg = gtable_add_grob(leg, l2, t=3, l=1) leg = gtable_add_grob(leg, l3, t=4, l=1) leg = gtable_add_grob(leg, t1, t=2, l=2) leg = gtable_add_grob(leg, t2, t=3, l=2) leg = gtable_add_grob(leg, t3, t=4, l=2) # give title (if needed) leg = gtable_add_grob(leg, textgrob("legend"), t=1, l=1, r=2) # ggplot grob plot1 g = ggplotgrob(plot1) # position of panel, # add column right of panel, # put legend column, # , add spacing column pos = g$layout[grepl("panel", g$layout$name), c('t', 'l')] g = gtable_add_cols(g, sum(leg$widths), pos$l) g = gtable_add_grob(g, leg, t = pos$t, l = pos$l + 1) g = gtable_add_cols(g, unit(6, "pt"), pos$l) # draw grid.newpage() grid.draw(g)
Comments
Post a Comment