如何在ggplot2中分别缩放线和点的大小
Posted
技术标签:
【中文标题】如何在ggplot2中分别缩放线和点的大小【英文标题】:How to scale the size of line and point separately in ggplot2 【发布时间】:2016-04-25 22:16:24 【问题描述】:代码如下:
set.seed(123)
d1=data.frame(x=runif(10),y=runif(10),z=runif(10,1,10))
d2=data.frame(x=runif(10),y=runif(10),z=runif(10,100,1000))
ggplot()+geom_point(aes(x,y,size=z),data=d1)+
geom_line(aes(x,y,size=z),data=d2)
结果是这样的:
点的大小太小,所以我想将其大小更改为scale_size
。但是,似乎线和点都受到了影响。所以我想知道是否有办法用单独的图例分别缩放线和点?
【问题讨论】:
只有一个尺寸图例。如果您想拥有单独的图例,则需要为其中一个使用其他内容,例如linetype
或 color
。
如果积分size=z*100
是否可以创建另一个尺寸图例?也许对于这个简单的例子可以用linetype
或者color
来代替,但是如果linetype
或者color
已经用过或者不适合这个图,那么我们还是需要解决这个问题。 @MikeWise
我认为可以使用 2.0.0 中的新功能扩展 ggplot2
以提供新的图例,但我已经仔细阅读了可用的文档,但如何做到这一点并不明显这次。恐怕现在您将不得不使用解决方法。要么滥用另一个传说,要么用geom_text
等和/或grid
grobs 构造一些东西。
其实我是想想办法把图例在点和线之间分开,而不是让点更明显。@mtoto
【参考方案1】:
我能想到的两种方法是 1) 结合两个传奇 grobs 或 2) 破解另一个传奇美学。 @Mike Wise 在上面的 cmets 中提到了这两个。
方法 #1: 使用 grobs 在同一个图中组合 2 个单独的图例。
我使用answer 中的代码来获取图例。 Baptiste 的arrangeGrob vignette 是一个有用的参考。
library(grid); library(gridExtra)
#Function to extract legend grob
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]]
legend
#Create plots
p1 <- ggplot()+ geom_point(aes(x,y,size=z),data=d1) + scale_size(name = "point")
p2 <- ggplot()+ geom_line(aes(x,y,size=z),data=d2) + scale_size(name = "line")
p3 <- ggplot()+ geom_line(aes(x,y,size=z),data=d2) +
geom_point(aes(x,y, size=z * 100),data=d1) # Combined plot
legend1 <- g_legend(p1)
legend2 <- g_legend(p2)
legend.width <- sum(legend2$width)
gplot <- grid.arrange(p3 +theme(legend.position = "none"), legend1, legend2,
ncol = 2, nrow = 2,
layout_matrix = rbind(c(1,2 ),
c(1,3 )),
widths = unit.c(unit(1, "npc") - legend.width, legend.width))
grid.draw(gplot)
注意printing:使用arrangeGrob()
而不是grid.arrange()
。我不得不使用 png; grid.draw; dev.off
来保存 (arrangeGrob) 图。
方法#2:破解另一个美学传奇。
MilanoR 在这方面有一篇很棒的帖子,重点关注颜色而不是大小。 更多 SO 示例:1) discrete colour 和 2) colour gradient。
#Create discrete levels for point sizes (because points will be mapped to fill)
d1$z.bin <- findInterval(d1$z, c(0,2,4,6,8,10), all.inside= TRUE) #Create bins
#Scale the points to the same size as the lines (points * 100).
#Map points to a dummy aesthetic (fill)
#Hack the fill properties.
ggplot()+ geom_line(aes(x,y,size=z),data=d2) +
geom_point(aes(x,y, size=z * 100, fill = as.character(z.bin)),data=d1) +
scale_size("line", range = c(1,5)) +
scale_fill_manual("points", values = rep(1, 10) ,
guide = guide_legend(override.aes =
list(colour = "black",
size = sort(unique(d1$z.bin)) )))
【讨论】:
这就是我需要的。谢谢! 另一个问题是size
会同时控制线和点,如果我在Approach #2中设置range = c(1,3)
,那么我该如何分别控制它们? @oshun
你不能。如果您想要更多控制,请使用方法 1。如果您想使用方法 2,则点和线的比例都相同。请注意,解决方案 #2 通过乘以 100 将点(范围 = 2 到 10)转换为与线(范围 140-905)相同的比例。要更改它们相对于彼此的大小,请更改此比例因子。尝试点*50(相对于线的较小点)或点*200(较大点)。将您的比例范围减少到c(1,3)
,将转换后的大小限制在 1-3 之间,这似乎适得其反。为什么不增加可能的尺寸范围?【参考方案2】:
我是编程菜鸟,但你可以试试这个方法。如您所见,我的代码使用点和路径。我定义了路径数长度的向量。我的线条大小为 1。然后我在该向量的后面添加我的点的大小。
size_vec<-c(rep(1, length(unique(Data$Satellite))), 1.4, 4.6, 4.2, 5.5)
plot <- ggplot(data) +
geom_point(aes(x = x_cor, y = y_cor, shape=Type, size=Type)) +
geom_path(aes(x = x_cor, y = y_cor, group = Tour, size=factor(Satellite))) +
scale_size_manual(values = size_vec, guide ='none')
【讨论】:
以上是关于如何在ggplot2中分别缩放线和点的大小的主要内容,如果未能解决你的问题,请参考以下文章
origin 两种不同的X轴,画出图像后怎么将这两个图像分别设置成线和点?
ggplot2:如何动态包装/调整大小/重新缩放 x 轴标签,使它们不会重叠
R语言ggplot2可视化:ggplot2可视化基本散点图(scatter plot)通过在theme_bw中指定参数base_size来改变轴标签的大小并控制网格线和轴标签的大小