r - ggplot: "size-robust" way to place horizontal legend at the bottom-right -


i trying place horizontal legend @ bottom-right corner, outside of plotting area.

i realize has been discussed before. however, after long frustrating morning, wasn't able reach "size-robust" solution.

here 3 solutions i've found:

  • when set legend.position bottom: legend placed @ bottom-center, yet fail push right side using legend.justification
  • when set legend.position c(1,0): legend placed @ bottom-right corner. however, legend placed inside plot.
  • when add plot.margin , push legend.position further down: legend placed @ bottom-right corner , outside of plot. however, when change size of plotting area, legend not correctly positioned more.


incorrect positioning of third solution:

enter image description hereenter image description here


reproducible code:

# generate random data------  sample.n = 50 sample.data = data.frame(x = runif(sample.n,0,1), y = runif(sample.n,0,1), value = runif(sample.n,0,10))  # plot ------  library(ggplot2)  # margins fine. , if change size of plotting area, legend bottom- centered # problem: can't push right side   ggplot(sample.data, aes(x = x, y = y, color = value)) + geom_point() +    theme(legend.direction = "horizontal", legend.position = "bottom")   # pushed bottom-right  # problem: legend inside plot ggplot(sample.data, aes(x = x, y = y, color = value)) + geom_point() +    theme(legend.direction = "horizontal",legend.position = c(1,0)) # problem: inside plot   # placed @ bottom-right corner outside plot region  # problem: if change size of plotting region, legend not cornred ggplot(sample.data, aes(x = x, y = y, color = value)) + geom_point() +    theme(legend.direction = "horizontal", legend.position = c(0.9,-0.2),           plot.margin = unit(c(1, 1, 5, 1), "lines"))   

theme-legend's documentation:

legend.position position of legends ("none", "left", "right", "bottom", "top", or two-element numeric vector)

legend.justification anchor point positioning legend inside plot ("center" or two-element numeric vector)

edit using 2.2.0, legend can pushed right using legend.justification , legend.margin in theme.

# generate random data------  sample.n = 50 sample.data = data.frame(x = runif(sample.n,0,1), y = runif(sample.n,0,1), value = runif(sample.n,0,10))  # plot ------  library(ggplot2) library(gtable) library(grid)  p = ggplot(sample.data, aes(x = x, y = y, color = value)) + geom_point() +    theme(legend.direction = "horizontal", legend.position = "bottom",           legend.box.background = element_rect(colour = "black"))  p + theme(legend.justification = "right",           legend.margin = margin(t = 2, r = 0, b = 2, l = 2, unit = "mm")) 

enter image description here


for worth, leave original answer updated ggplot version 2.2.0.

what have done here extract legend plot, wrap legend in viewport viewport positioned right, put legend plot, , remove original legend.

# generate random data------  sample.n = 50 sample.data = data.frame(x = runif(sample.n,0,1), y = runif(sample.n,0,1), value = runif(sample.n,0,10))  # plot ------  library(ggplot2) library(gtable) library(grid)  p = ggplot(sample.data, aes(x = x, y = y, color = value)) + geom_point() +    theme(legend.direction = "horizontal", legend.position = "bottom")  # ggplot grob g = ggplotgrob(p)  # legend index = which(g$layout$name == "guide-box") leg = g$grobs[[index]]  # wrap legend in viewport leg$vp = viewport(x = unit(1, "npc"), width = sum(leg$widths), = "right")  ### put legend plot      # first, current location of legend pos = g$layout[index, ] g = gtable_add_grob(g, leg, t = pos$t, l = pos$l)  # remove original legend g$grobs <- g$grobs[-index] g$layout <- g$layout[-index, ]  # draw chart grid.newpage() grid.draw(g) 

enter image description here

note legend has been moved right, right edge of legend not quite align right edge of plot panel. because legend has internal margin. legend has margin margin set 0 mm. legend align plot panel requires bit more fiddling. in follows, internal margin (and legend margin) set 0. also, legend , internal part of legend wrapped in right justified viewports.

# ggplot grob g = ggplotgrob(p)  # legend index = which(g$layout$name == "guide-box") leg = g$grobs[[index]]  # remove legend right margin , internal margin leg$widths[4] = unit(0, "mm") leg$grobs[[1]]$widths[5] = unit(0, "mm")  # wrap legend in viewport leg$vp = viewport(x = unit(1, "npc"), width = sum(leg$widths), = "right")  # wrap internal part of legend in right justified viewport leg$grobs[[1]]$vp = viewport(x = unit(1, "npc"), width = sum(leg$grobs[[1]]$widths), = "right")  ### put legend plot      # first, current location of legend pos = g$layout[index, ] g = gtable_add_grob(g, leg, t = pos$t, l = pos$l)  # remove original legend g$grobs <- g$grobs[-index] g$layout <- g$layout[-index, ]  # draw chart grid.newpage() grid.draw(g) 

enter image description here


Comments

Popular posts from this blog

sequelize.js - Sequelize group by with association includes id -

android - Robolectric "INTERNET permission is required" -

java - Android raising EPERM (Operation not permitted) when attempting to send UDP packet after network connection -