ggplot BARCPLOT:如何使用对数缩放y轴显示小正数

ggplot BARCPLOT:如何使用对数缩放y轴显示小正数,r,ggplot2,logarithm,geom-bar,R,Ggplot2,Logarithm,Geom Bar,主要问题:我希望将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

主要问题:我希望将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_段
进行说明,这样我就可以创建扩展到任意范围的“条”(实际上是宽线段)。为了实现这一点,我还必须手动执行所有的规避操作,这就是为什么
x
映射看起来很奇怪的原因

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

无法显示下降到零的条形图,因为对数刻度上的零是图形底部下方的无限距离。例如,我们可以通过将下面代码中的
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")

这里有一点黑客攻击,以显示如果您尝试在对数刻度上获取从零开始的条会发生什么。我使用了
geom_段
进行说明,这样我就可以创建扩展到任意范围的“条”(实际上是宽线段)。为了实现这一点,我还必须手动执行所有的规避操作,这就是为什么
x
映射看起来很奇怪的原因

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

无法显示下降到零的条形图,因为对数刻度上的零是图形底部下方的无限距离。例如,我们可以通过将下面代码中的
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")

条形图以零为单位定义。你的数字很小。非常小的数字的对数是负数。这个条从零到负数。我有点困惑,因为我没有对数据本身进行日志转换,所以这些数字仍然是正数。此外,如果绘制数据,您将看到y轴单位仍然从1e-6(底部)增加到1e-3,但奇怪的是,这些条从顶部到底部“下降”,即从较大的数字到较小的数字。我只想以对数比例查看数据,而不是转换数据本身。我希望我说的有道理你绝对是在转换数据
scale\u y\u log10()
log会在打印数据之前对其进行转换。不,它会对记号标签的数据进行反向转换。绝对不是虫子。我也很担心你这么做。条形图绝对应该从0开始,但不能用对数10标度(
log10(0)
==
-Inf
),大多数人都会做出非常糟糕的结论,因为他们会在头脑中线性比较条形图,并且必须不断记住这是一个对数标度,并尝试对其进行补偿。如果问题是E和其他条形图对之间的YUGE差异,则可以使用带有自由Y刻度的镶嵌面来补偿,并使其紧凑。条形图以零为单位定义。你的数字很小。非常小的数字的对数是负数。这个条从零到负数。我有点困惑,因为我没有对数据本身进行日志转换,所以这些数字仍然是正数。此外,如果绘制数据,您将看到y轴单位仍然从1e-6(底部)增加到1e-3,但奇怪的是,这些条从顶部到底部“下降”,即从较大的数字到较小的数字。我只想以对数比例查看数据,但不想转换数据