Clifford
Clifford

Reputation: 21

How to add a custom legend to plot with ggplot?

I want to add a new legend to my plot. But I hope the legend is all customized. I add the label for every point by geom_text_repel. The new legend describes the of character of the labels.

Before

After

Upvotes: 1

Views: 4787

Answers (1)

eipi10
eipi10

Reputation: 93761

You can create a legend by creating "dummy" data that contains the legend key labels. You would then "plot" the dummy data in order to generate the legend, but use blank symbols so that nothing actually gets plotted.

library(ggplot2)
theme_set(theme_classic())    

# Fake data for plotting
set.seed(2)
val = sapply(sample(1:4,30,replace=TRUE), function(x) paste(sort(sample(c('c','u','x','t'), x)), collapse=""))
dat = data.frame(x=runif(30), y=runif(30), val) 

# Dummy data for creating the legend
leg = data.frame(x1=rep(0,4), y1=rep(0,4), ll = c("c: coor","u: url","x: xss","t: text"))

ggplot(data=dat, aes(x,y)) + 
  geom_text(aes(label=val)) +
  geom_point(data=leg, aes(x1, y1, colour=ll)) +
  theme(legend.key.size=unit(15,"pt"),
        legend.title=element_blank(),
        legend.margin=margin(l=0),
        legend.text=element_text(size=12)) +
  scale_colour_manual(values=rep("#00000000", 4))

enter image description here

You could also use geom_text to place the "legend" annotations directly:

leg = data.frame(ll = sort(c("c: coor","u: url","x: xss","t: text")))
leg$y = seq(mean(dat$y) + 0.05*diff(range(dat$y)), 
            mean(dat$y) - 0.05*diff(range(dat$y)),
            length=4)
leg$x = 1.07 * max(dat$x)

ggplot(data=dat, aes(x,y)) + 
  geom_text(aes(label=val)) +
  geom_text(dat=leg, aes(label=ll), hjust=0, colour="red") +
  annotate(xmin=1.05 * max(dat$x), xmax=1.18 * max(dat$x), ymin=0.95*min(leg$y), ymax=1.04*max(leg$y), 
           geom="rect", fill=NA, colour="black") + 
  scale_x_continuous(limits=c(min(dat$x), 1.18*max(dat$x)))

enter image description here

Upvotes: 1

Related Questions