如何在一个ggplot中有两个不同大小的图例? [英] How to have two different size legends in one ggplot?

查看:230
本文介绍了如何在一个ggplot中有两个不同大小的图例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我绘制这个玩具数据:

  lev <-c(A,B,C ,D)

节点< - data.frame(ord = c(1,1,1,2,2,3,3,4),品牌=
因子(c(A,B,C,B,C,D,B,D),levels = lev),
thick = c(16 ,9,9,16,4,1,4,1))

edge< - data.frame(ord1 = c(1,1,2,3),brand1 = factor(c (C,A,B,B),
levels = lev),ord2 = c(2,2,3,4),brand2 = c(C,B ,B,D),
N1 = c(2,1,2,1),N2 = c(5,5,2,1))

ggplot ()+
geom_point(data = nodes,
aes(x = ord,y = brand,size = sqrt(thick)),
color =black,shape = 16,show .legend = T)+
scale_x_continuous(limits = c(1,4),breaks = seq(0,4,1),
minor_breaks = NULL)+
geom_segment(data = edge ,
aes(x = ord1,y = brand1,xend = ord2,yend = brand2),
color =blue,size = edge $ N2 / edge $ N1)+
ylim (lev)+
theme_bw()

如预期的那样,我得到了这个图。



我想添加另一个图例(节点下方) N2 / N1。

PD:
按照您的一些建议...

  ggplot()+ 
geom_segment(data = edge,
aes(x = ord1,y = brand1,xend = ord2,yend = brand2,size = N2 / N1),
color =blue,show.legend = T)+
geom_point(data = nodes,
aes(x = ord,y = brand,size = thick),
color =black,shape = 16,show.legend = T)+
scale_x_continuous(limits = c(1,4),breaks = 0:4,
minor_breaks = NULL)+
scale_size_continuous(trans =sqrt,breaks = c(1,4,9,16))+
ylim(lev)+ theme_bw()



我得到了这个传说,但它与另一个重叠。



我可以尝试使用颜色代替宽度:

  ggplot( )+ geom_segment(data = edge,aes(x = ord1,y = brand1,xend = ord2,yend = brand2,alpha = N2 / N1),size = 1,show.legend = T)+ 
geom_point data = nodes,aes(x = ord,y = brand,size = thick),color =black,shape = 16,show.legend = T)+
scale_x_continuous(limits = c(1,4) ,break = seq(0,4,1),minor_breaks = NULL)+ scale_size_continuous(trans =sqrt,breaks = c(1,4,9,16))+
ylim(lev)+ theme_bw( )



或不同的字母



尽管我更喜欢宽度最初的方法,因为在我的真实情节中,我会有多条线穿过。



PD:任何带格或任何其他替代方案的解决方案都可以导出为svg或vectorial pdf?



PD2:我找到了另一个问题,薄点不能正确缩放,有时不可能强制ggplot显示适当的图例:


Imagine I plot this toy data:

lev <- c("A", "B", "C", "D")

nodes <- data.frame(ord=c(1,1,1,2,2,3,3,4), brand=
  factor(c("A", "B", "C","B", "C","D", "B","D"), levels=lev), 
  thick=c(16,9,9,16,4,1,4,1))

edge <-  data.frame(ord1=c(1,1,2,3), brand1=factor(c("C","A","B","B"), 
  levels=lev),ord2=c(2,2,3,4), brand2=c("C","B","B","D"),
  N1=c(2,1,2,1), N2=c(5,5,2,1))

ggplot() +
  geom_point(data = nodes,
    aes(x = ord, y = brand, size = sqrt(thick)),
    color = "black", shape = 16, show.legend = T) + 
  scale_x_continuous(limits=c(1, 4), breaks=seq(0,4,1),
    minor_breaks = NULL) + 
  geom_segment(data = edge,
    aes(x = ord1, y = brand1, xend = ord2, yend = brand2), 
    color = "blue", size = edge$N2/edge$N1) +
  ylim(lev) +
  theme_bw()

I get this plot, as expected.

I would like to add another legend (below the nodes) relating the width of the segments and N2/N1.

PD: Following some of your suggestions...

ggplot() + 
  geom_segment(data = edge,
    aes(x = ord1, y = brand1, xend = ord2, yend = brand2, size = N2/N1), 
    color = "blue", show.legend = T) +
  geom_point(data = nodes,
    aes(x = ord, y = brand, size = thick),
    color = "black", shape = 16, show.legend = T) + 
  scale_x_continuous(limits = c(1, 4), breaks = 0:4,
    minor_breaks = NULL) +
  scale_size_continuous(trans = "sqrt", breaks = c(1,4,9,16))  + 
  ylim(lev) +  theme_bw()

I got the legend but it overlaps with the other one.

I can try using colors instead of widths:

ggplot()+ geom_segment(data=edge, aes(x=ord1, y=brand1, xend=ord2, yend=brand2, alpha=N2/N1) , size=1 ,show.legend = T) +
  geom_point(data=nodes,aes(x=ord, y=brand, size=thick), color="black", shape=16,show.legend = T) + 
  scale_x_continuous(limits=c(1, 4), breaks=seq(0,4,1), minor_breaks = NULL) + scale_size_continuous(trans = "sqrt", breaks=c(1,4,9,16))  + 
   ylim(lev) + theme_bw()

Or varying alpha

Though I prefer the original approach with widths because in my real plot I'll have many lines crossing.

PD: Any solution with lattice or any alternative able to be exported as svg or vectorial pdf?

PD2: I've found another problem, thin points aren't scaled properly and sometimes is impossible to force ggplot to show a proper legend: How can I force ggplot to show more levels on the legend?

解决方案

Sometimes ggplot may not be the best tool for the job. it pays to be familiar with some other plotting options for these instances, with R's base graphics system being reasonably versatile.

Here's how you might do it in base graphics:

lev <- c("A", "B", "C", "D")    
nodes <- data.frame(ord=c(1,1,1,2,2,3,3,4), brand=
    factor(c("A", "B", "C","B", "C","D", "B","D"), levels=lev), 
  thick=c(16,9,9,16,4,1,4,1))   
edge <-  data.frame(ord1=c(1,1,2,3), 
  brand1=factor(c("C","A","B","B"), levels=lev),
  ord2=c(2,2,3,4), 
  brand2=factor(c("C","B","B","D"), levels=lev),
  N1=c(2,1,2,1), N2=c(5,5,2,1))

png(width = 6, height = 4, units = 'in',res=300)
par(xpd=FALSE, mar = c(5, 4, 4, 15) + 0.1)
plot(NULL, NULL,  xaxt = "n", yaxt = "n",
  xlim = c(1,4), ylim = c(1,4), 
  xlab = 'ord', ylab = 'brand')
axis(side = 1, at = 1:4)
axis(side = 2, at = 1:4, labels = LETTERS[1:4])
grid()
par(xpd=TRUE)
segments(edge$ord1, as.integer(edge$brand1), 
  edge$ord2, as.integer(edge$brand2), 
  lwd = 4*edge$N2/edge$N1,
  col='blue')

points(nodes$ord, nodes$brand, cex=sqrt(nodes$thick), pch=16)
legend(4.5,4,
  legend = as.character(c(1,2,4,8,16)), 
  pch = 16, 
  cex = 1.5,
  pt.cex = sqrt(c(1,2,4,8,16)))
legend(6,4,
  legend = as.character(1:5), 
  lwd = 4*(1:5), 
  col = 'blue',
  cex = 1.5)
dev.off()

这篇关于如何在一个ggplot中有两个不同大小的图例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆