2016-12-08 97 views
0

主要问题:我想要显示从0到1.0的数据作为向上的条(从0开始),但不希望间隔等距但日志间隔。ggplot barplot:如何使用日志缩放y轴显示小的正数

我想在下面的数据集中显示标记为“均值”的列作为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 

下面的代码正确地产生与误差棒分组barplot

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)) 

但奇怪的是,酒吧从上面掉下来,但我只是想让他们上升(像往常一样),不知道我做错了什么。

谢谢

+2

barplots以零来定义。你有很少的数字。非常小的数字是负数。酒吧从零下降到负数。 – Axeman

+0

我有点困惑,因为我不是日志转换数据本身,所以数字仍然是积极的。此外,如果绘制数据,则会看到y轴单位仍然从1e-6(底部)增加到1e-3,但奇怪的是,条从顶部到底部“下降”,即从较大的数字到较小的数字。我只想查看日志级别的数据,但不能转换数据本身。我希望我有道理 –

+2

你是绝对的日志转换数据。 'scale_y_log10()'日志在绘制数据之前转换数据。 – hrbrmstr

回答

4

这里有点黑客显示,如果你试图获取在零上日志规模开始吧会发生什么。我已经使用geom_segment进行了说明,以便我可以创建延伸到任意范围的“条”(实际上是宽线段)。为了做到这一点,我还必须手动进行所有的避让,这就是为什么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]) 

enter image description here

如果你想坚持数比例,也许绘制点会是一个更好的办法:

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") 

enter image description here