Reputation: 437
I create many plots in R with data input from another script that are held in a separate variable each. I put the variables in a string and force a line break with \n
. This works as intended, but the legend is not justified at all. xjust
and yjust
seem to not do anything. Also, when placing the legend e.g. in bottomright, it stretches beyond the margin of the plot. Any idea how I can properly place my legend justified at the corner of a plot?
Here a reproducible code snippet:
plot(c(0,3), c(0,3), type="n", xlab="x", ylab="y")
a <- 2.3456
b <- 3.4567
c <- 4.5678
d <- 5.6789
Corner_text <- function(text, location = "bottomright"){
legend(location, legend = text, bty = "o", pch = NA, cex = 0.5, xjust = 0)
}
Corner_text(sprintf("a = %3.2f m\n b = %3.2f N/m\UB2\n c = %3.2f deg\n d = %3.2f perc", a, b, c, d))
Upvotes: 3
Views: 6364
Reputation: 35307
An example on how to do this using ggplot2
, where legend creation is automatic when you map a variable in aes
:
library(ggplot2)
units <- c('m', 'N/m\UB2', 'deg', 'perc')
p <- ggplot() + geom_hline(aes(yintercept = 1:4, color = letters[1:4])) + #simple example
scale_color_discrete(name = 'legend title',
breaks = letters[1:4],
labels = paste(letters[1:4], '=', c(a, b, c, d), units))
Or inside the plot:
p + theme(legend.position = c(1, 0), legend.justification = c(1, 0))
Or closer to your easthetic:
p + guides(col = guide_legend(keywidth = 0, override.aes = list(alpha = 0))) +
theme_bw() +
theme(legend.position = c(1, 0), legend.justification = c(1, 0),
legend.background = element_rect(colour = 'black'))
Upvotes: 3
Reputation: 24074
legend
is usually used to explain what the points
or lines
(and the different colors) represent. Therefore, inside the legend box (bty
) there is a space where the lines/points are supposed to be. This probably explains why you think your text is not left-justified (you also have a problem of space after your line-break (\n
): if you put a space after a line-break, it will be your first character on the next line, hence the text does not appear justified).
In your example, you don't have lines or points to explain, hence, I would use text
rather than legend
.
To know where "bottomright" is on your axes, you can use the graphical parameters par("xaxp")
and par("yaxp")
(it gives you the values of first and last ticks and the number of ticks on your axis).
On the x-axis, from the last tick, you need to shift left to have space for the widest line.
In R code
, it gives:
# your plot
plot(c(0,3), c(0,3), type="n", xlab="x", ylab="y")
# your string (without the extra spaces)
text_to_put <- sprintf("a = %3.2f m\nb = %3.2f N/m\UB2\nc = %3.2f deg\nd = %3.2f perc", a, b, c, d)
# the width of widest line
max_str <- max(strwidth(strsplit(text_to_put, "\n")[[1]]))
# put the text
text(x=par("xaxp")[2]-max_str, y=par("yaxp")[1], labels=text_to_put, adj=c(0, 0))
# if really you need the box (here par("usr") is used to know the extreme values on both axes)
x_offset <- par("xaxp")[1]-par("usr")[1]
y_offset <- par("yaxp")[1]-par("usr")[3]
segments(rep(par("xaxp")[2]-max_str-x_offset, 2), c(par("usr")[3], par("yaxp")[1]+strheight(text_to_put)+y_offset), c(par("xaxp")[2]-max_str-x_offset, par("usr")[2]), rep(par("yaxp")[1]+strheight(text_to_put)+y_offset, 2))
Upvotes: 3