Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

r - Control over legends of multiple layer plot in ggplot2

My question is closely related to R: Custom Legend for Multiple Layer ggplot , and to Format legend for multiple layers ggplot2 namely: I want to create custom legends for multiple-layer plot. However, there is a subtle difference: In the original questions, the desired effect was to separate from two different groupping methods: fill and color and that's why it was possible to use two different scale_XXX functions. In my case I create a plot that contains points (one layer) and lines (second layer). Both layers are differentiated by color:

x <- seq(0, 10, .1)
y <- sin(x)
lbl <- ifelse(y > 0, 'positive', 'non-positive')
data.one <- data.frame(x=x, y=y, lbl=lbl)

data.two <- data.frame(x=c(0, 10, 0, 10), y=c(-0.5, -0.5, 0.5, 0.5), classification=c('low', 'low', 'high', 'high'))
plt <- ggplot(data.one) + geom_point(aes(x, y, color=lbl)) + scale_color_discrete(name='one', guide='legend')
plt <- plt + geom_line(data=data.two, aes(x, y, color=classification)) + scale_color_discrete(name='two', guide='legend')
print(plt)

Here is the result:

before

What I want is to separate the legends for points and lines, so that the legend looks like this:

after

I could not find a way to adopt the approach of the cited questions to my situation. Any ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The following is a hack. It extracts the legends from temporary plots and then combines everything using grid.arrange.

g_legend<-function(a.gplot){
  tmp <- ggplot_gtable(ggplot_build(a.gplot))
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg]]
  return(legend)}

n <- 4; cols <- hcl(h=seq(15, 375-360/n, length=n)%%360, c=100, l=65)

cols1 <- cols[4:3]
names(cols1) <-  c("positive", "non-positive")
plt_1 <- ggplot(data.one) + 
  geom_point(data=data.one,aes(x, y, color=lbl)) +
  scale_color_manual(values=cols1)


cols2 <- cols[1:2]
names(cols2) <-  c("high", "low")
plt_2 <- ggplot(data.one) + 
  geom_line(data=data.two, aes(x, y, color=classification)) +
  scale_color_manual(values=cols2)
  

mylegend_1<-g_legend(plt_1)
mylegend_2<-g_legend(plt_2)

plt <- ggplot(data.one) + 
  geom_point(data=data.one,aes(x, y, color=lbl)) +
  geom_line(data=data.two, aes(x, y, color=classification)) +
  scale_color_discrete(guide="none")

library(gridExtra)
grid.arrange(plt,
             arrangeGrob(mylegend_1, mylegend_2, nrow=6),
             ncol=2,widths=c(7,1))

enter image description here

You'd need to fiddle a bit more to get the justification as in your expected output.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...