ggplot barplot:如何显示带有对数刻度 y 轴的小正数

ggplot barplot : How to display small positive numbers with log scaled y-axis

主要问题:我想将 0 到 1.0 的数据显示为向上条(从 0 开始),但不希望间隔等距而是对数间隔。

我正在尝试将下面数据集中标记为 "mean" 的列显示为 ggplot 中的条形图,但由于数字非常小,我想在对数刻度上显示 y 轴而不是比日志转换数据本身。换句话说,我想要 y 轴标签为 0、1e-8、1e-6、1e-4、1e-2 和 1e-0 的直立条(即从 0 到 1.0,但间隔按对数缩放)。

下面的解决方案不起作用,因为条是倒转的。

> print(df)
        type         mean           sd           se snp
V7    outer 1.596946e-07 2.967432e-06 1.009740e-08   A
V8    outer 7.472417e-07 6.598652e-06 2.245349e-08   B
V9    outer 1.352327e-07 2.515771e-06 8.560512e-09   C
V10   outer 2.307726e-07 3.235821e-06 1.101065e-08   D
V11   outer 4.598375e-06 1.653457e-05 5.626284e-08   E
V12   outer 5.963164e-07 5.372226e-06 1.828028e-08   F
V71  middle 2.035414e-07 3.246161e-06 1.104584e-08   A
V81  middle 9.000131e-07 7.261463e-06 2.470886e-08   B
V91  middle 1.647716e-07 2.875840e-06 9.785733e-09   C
V101 middle 3.290817e-07 3.886779e-06 1.322569e-08   D
V111 middle 6.371170e-06 1.986268e-05 6.758752e-08   E
V121 middle 8.312429e-07 6.329386e-06 2.153725e-08   F

下面的代码正确生成了带有误差线的分组条形图

ggplot(data=df, aes(x=snp,y=mean,fill=type))+
  geom_bar(stat="identity",position=position_dodge(),width=0.5) + 
  geom_errorbar(aes(ymin=mean-se, ymax=mean+se),width=.3, position=position_dodge(.45)) 

但是,我想使 y 轴对数缩放,所以我在 scale_y_log10() 中添加如下:

 ggplot(data=df, aes(x=snp,y=mean,fill=type))+
  geom_bar(stat="identity",position=position_dodge(),width=0.5) + scale_y_log10() +
  geom_errorbar(aes(ymin=mean-se, ymax=mean+se),width=.3, position=position_dodge(.45)) 

但奇怪的是,条形图从上方掉落,但我只是希望它们向上(像往常一样)并且不知道我做错了什么。

谢谢

这里有一些技巧可以说明如果您尝试在对数刻度上获取从零开始的条柱会发生什么。我使用 geom_segment 进行说明,因此我可以创建 "bars"(实际上是宽线段)延伸到任意范围。为了完成这项工作,我还必须手动完成所有闪避,这就是 x 映射看起来很奇怪的原因。

在下面的示例中,比例从 y=1e-20 变为 y=1。 y 轴间隔是对数标度的,这意味着从 1e-20 到 1e-19 的物​​理距离与从 1e-8 到 1e-7 的物理距离相同,即使这些间隔的大小相差万亿倍。

无法显示下降到零的柱状图,因为对数刻度上的零是图表底部下方的无限距离。例如,我们可以通过在下面的代码中将 1e-20 更改为 1e-100 来接近零。但这只会使数据值之间本已很小的物理距离变得更小,从而更难区分。

条形图还以另一种方式产生误导,因为正如@hrbrmstr 指出的那样,我们的大脑线性处理沿条形图的距离,但沿条形图的每个距离增量所表示的幅度变化大约为 10 倍在下面的示例中每隔几毫米。条形图根本没有编码有关数据的有意义信息。

ggplot(data=df, aes(x=as.numeric(snp) + 0.3*(as.numeric(type) - 1.5), 
                    y=mean, colour=type)) +
  geom_errorbar(aes(ymin=mean-se, ymax=mean+se), width=.3) +
  geom_segment(aes(xend=as.numeric(snp) + 0.3*(as.numeric(type) - 1.5),
                   y=1e-20, yend=mean), size=5) +
  scale_y_log10(limits=c(1e-20, 1), breaks=10^(-100:0), expand=c(0,0)) +
  scale_x_continuous(breaks=1:6, labels=LETTERS[1:6])

如果您想坚持使用对数刻度,也许绘图点会是更好的方法:

pd = position=position_dodge(.5)
ggplot(data=df, aes(x=snp,y=mean,fill=type))+
  geom_errorbar(aes(ymin=mean-se, ymax=mean+se, colour=type), width=.3, position=pd) +
  geom_point(aes(colour=type), position=pd) +
  scale_y_log10(limits=c(1e-7, 1e-5), breaks=10^(-10:0)) +
  annotation_logticks(sides="l")