Jack Aidley
Jack Aidley

Reputation: 20107

Is it possible to position the legend to the top right of a ggplot in R?

I am trying to create a theme for ggplot that I can then use for all my graphs and getting them looking both nice and nice and uniform. I want to move the legend from its current position vertically centred on the right to being aligned with the top of the graph on the right, as indicated by the red arrow below.

Desired legend movement

I cannot figure it out. I can get it to position inside the plot by using legend.position but if I then do legend.justification = c(0.0, 1.0) it pushes the legend outside of the area it plots and it gets cut off completely. I know I could do it individually for each graph by messing around with grobs and gtables for each individual graph but I don't want to have to do that every time I plot a graph.

Is there anyway to do this with a theme?

Upvotes: 33

Views: 33172

Answers (4)

mindlessgreen
mindlessgreen

Reputation: 12112

Seems like it's finally possible with ggplot2 2.2.0

enter image description here

library(ggplot2)
ggplot(mpg, aes(displ, hwy, colour=fl)) + 
  geom_point() + 
  theme(legend.justification = "top")

Upvotes: 47

baptiste
baptiste

Reputation: 77096

library(ggplot2)

p <- ggplot(iris, aes(Sepal.Length, Sepal.Width, col=Species)) + 
  geom_point() +
  theme(legend.background = element_rect(colour = "black", size = 0.5),
        panel.background = element_rect(colour = "black", size = 0.5))

g <- ggplotGrob(p)

leg <- g$grobs[[8]]
leg$heights[3] <- unit(1,"null")
leg$heights[1] <- unit(0,"null")
# grid.newpage()
# grid.draw(leg)
g$grobs[[8]] <- leg
grid.newpage()
grid.draw(g)

enter image description here

Upvotes: 3

Andrie
Andrie

Reputation: 179428

Try experimenting with the theme options, in particular

  • legend.key.width
  • plot.margin

Try this:

library(ggplot2)

ggplot(iris, aes(Sepal.Length, Sepal.Width, col=Species)) + 
    geom_point() + 
    theme(
        legend.position=c(1,1), 
        legend.justification=c(0, 1), 
        legend.key.width=unit(1, "lines"), 
        plot.margin = unit(c(1, 5, 0.5, 0.5), "lines")
    )

enter image description here

Upvotes: 7

tonytonov
tonytonov

Reputation: 25608

The simplest hack I've found is

ggplot(data.frame(x=1:3, y=1:3), aes(x=x, y=y, colour=x)) + geom_point() + 
  theme(plot.margin=unit(c(5,5,1,1),"cm"), legend.position=c(1.1, 1.1))

You can also play with legend.justification paramater, setting it e.g. to "top". enter image description here

Upvotes: 2

Related Questions