Maël
Maël

Reputation: 51954

Legend position based on coordinates in ggplot2

Using ggplot2's legend.position (and legend.justification), the two available parameters indicate the relative position of the legend, but what if I want to position the legend based on the coordinates of the plot? I can't find a way to do it.

This is strange as annotate gives an x and y argument that allows such things.

Here is some toy data

library(ggplot2)

ggplot(data = mtcars, aes(x = mpg,y = disp,color = factor(cyl))) +
  geom_point() +
  theme(legend.position = c(0.01,0.01),
        legend.justification = c(0,0))

Which gives: this

What about if I want the bottom-left corner of the legend to be on coordinates (10,100)?

Upvotes: 3

Views: 797

Answers (1)

Peter H.
Peter H.

Reputation: 2164

I don't think there is an easy way to do it. The only approach i could think of is to build the plot object to extract the ranges of the axes in order to convert (10, 100) into a relative coordinate that can be used with legend position. Admittedly, this is very hacky...

library(tidyverse)

p <- ggplot(data = mtcars, aes(x = mpg, y = disp, color = factor(cyl))) +
  geom_point()

ranges <- ggplot_build(p) %>% 
  pluck("layout", "panel_params", 1) %>% 
  `[`(c("x.range", "y.range"))

x <- (10 - ranges$x.range[1]) / (ranges$x.range[2] - ranges$x.range[1])
y <- (100 - ranges$y.range[1]) / (ranges$y.range[2] - ranges$y.range[1])

p + theme(legend.position = c(x, y), legend.justification = c(0, 0))

Created on 2021-07-21 by the reprex package (v1.0.0)

Upvotes: 3

Related Questions