修改ggplot2中的颜色比例图例以匹配线条大小

4

如何根据数据集中的列覆盖 ggplot2 图例指南中的 aes 大小值?

请参考以下示例(编辑 2:添加了 Trial C,并将线条尺寸改为使用对数刻度):

library(data.table)
set.seed(26798)

dt<-rbind(data.table(Trial="A",Value=rweibull(1000,1.0,0.5)),
      data.table(Trial="B",Value=rweibull(100,1.2,0.75)),
      data.table(Trial="C",Value=rweibull(10,1.3,0.8)))

# Add a count and something like a cumulative distribution:
dt2<-dt[order(Trial,Value),list(Value,N=.N),by=Trial][,list(Value,N,y=1-cumsum(N)/sum(N)),by=Trial]
dt2
##      Trial        Value    N     y
##   1:     A 0.0003628745 1000 0.999
##   2:     A 0.0013002615 1000 0.998
##   3:     A 0.0017002173 1000 0.997
##   4:     A 0.0022597343 1000 0.996
##   5:     A 0.0026608082 1000 0.995
##  ---                              
##1096:     B 1.6821827814  100 0.040
##1097:     B 2.2431595707  100 0.030
##1098:     B 2.5122479833  100 0.020
##1099:     B 2.5519954416  100 0.010
##1100:     B 2.6848412995  100 0.000

ggplot(dt2) +
  geom_line(aes(x=Value,y=y,group=Trial,color=Trial,size=N)) +
  scale_size(range=c(0.1, 2), trans="log") +
  guides(size=F, color=guide_legend(override.aes=list(size=2)))

三个试验的图表

我希望每个试验值在图例中的线条粗细与图表中的线条相匹配(例如,“A”应该粗,“B”应该细)。 编辑1: @Arun和@ChelseaE给出了手动调整每个线条粗细的好建议,但是我的实际数据集有许多因子级别并且不断变化,因此我需要使其“动态”。

@DidzisElferts在类似问题的答案中 (Control ggplot2 legend look without affecting the plot),展示了如何将大小设置为静态值。上面示例的最后一行中的size=2部分允许我更改图例的线条大小,但我希望它与图表中的线条大小匹配。使用size=N似乎是合理的,但它会出现“对象'N'未找到”的错误。正确的语法是什么?

期望的输出:

具有期望图例的三个试验的图表


1
我不明白:如果你希望行大小对应于Trial,为什么要将其映射到N呢? - baptiste
我在实现中可能做错了什么,但我的绘图意图是使用线条粗细来显示每个试验的观察次数不同(由N捕获)。然后我希望图例与图形匹配。我的实际数据有5到10条线而不是两条,当图例匹配时,在图中挑选出这些线条是有视觉帮助的。 - dnlbrky
2个回答

6
你需要为A和B分别设置适当的尺寸。你只设置了一个尺寸。试试这个:
p <- ggplot(dt2) +
geom_line(aes(x=Value,y=y,group=Trial,color=Trial,size=N)) +
scale_size(range=c(0.1, 2)) +
guides(size=FALSE, color=guide_legend(override.aes=list(size=c(2, .1))))

根据评论者的意见:

好的,如果是这样,你需要再做更多的工作(有可能有更简单的方法,但目前我想不到)。

scales <- c(0.1, 2) # the range you want: min, max
vals <- summary(lm(scales ~ c(min(dt2$N), max(dt2$N))))$coefficients[,1]
sizes <- vals[2] * unique(dt2$N) + vals[1]

ggplot(dt2) +
geom_line(aes(x=Value,y=y,group=Trial,color=Trial,size=N)) +
scale_size(range=scales) +
guides(size=FALSE, color=guide_legend(override.aes=list(size=sizes)))

这应该可行。试一下,如果有问题请告诉我。


感谢您的好建议,@Arun。然而,在我的实际数据集中,有很多值是不断变化的,所以我需要它更加“动态”。我已经更新了问题以反映这一点。 - dnlbrky
@dnlbrky,请检查编辑是否符合您的一般情况。如果有困难,请告诉我。 - Arun
谢谢,这个路线可行。根据个人喜好,我会使用以下修改: size = rescale(dt2[, .N, by=list(Trial)][order(Trial), log(N)], scales) - dnlbrky

1

尝试在guide_legend中添加大小范围:

ggplot(dt2) + geom_line(aes(x = Value, y = y, group = Trial, color = Trial, size = N)) + scale_size(range = c(0.1, 2)) + guides(size = F, color = guide_legend(override.aes = list(size = range(0.1,2))))

编辑:(可能有效,不确定)

您还可以尝试为N创建向量(N <- dt2$N),然后使用size = N

希望这有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接