使用scale_y_log10()在条形图中转换y轴

时间:2017-10-09 05:00:27

标签: r ggplot2

使用下面的data.frame,我想要一个y轴日志变换的条形图。

我得到了这个情节

enter image description here

使用此代码

ggplot(df, aes(x=id, y=ymean , fill=var, group=var)) +
  geom_bar(position="dodge", stat="identity",
           width = 0.7,
           size=.9)+
  geom_errorbar(aes(ymin=ymin,ymax=ymax),
                size=.25,   
                width=.07,
                position=position_dodge(.7))+
  theme_bw()

记录变换y轴以显示" low" B和D中的水平接近零,我用了

+scale_y_log10()

导致

enter image description here

有关如何转换第一个图的y轴的任何建议吗?

顺便说一句,我的数据中的一些值接近于零,但它们都不为零。

更新

@computermacgyver

尝试此suggested answer
ggplot(df, aes(x=id, y=ymean , fill=var, group=var)) +
  geom_bar(position="dodge", stat="identity",
           width = 0.7,
           size=.9)+
  scale_y_log10("y",
                breaks = trans_breaks("log10", function(x) 10^x),
                labels = trans_format("log10", math_format(10^.x)))+
  geom_errorbar(aes(ymin=ymin,ymax=ymax),
                size=.25,   
                width=.07,
                position=position_dodge(.7))+
  theme_bw()

我得到了

enter image description here

数据

dput(df)
structure(list(id = structure(c(7L, 7L, 7L, 1L, 1L, 1L, 2L, 2L, 
2L, 6L, 6L, 6L, 5L, 5L, 5L, 3L, 3L, 3L, 4L, 4L, 4L), .Label = c("A", 
"B", "C", "D", "E", "F", "G"), class = "factor"), var = structure(c(1L, 
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
3L, 1L, 2L, 3L), .Label = c("high", "medium", "low"), class = "factor"), 
    ymin = c(0.189863418, 0.19131948, 0.117720496, 0.255852069, 
    0.139624146, 0.048182771, 0.056593774, 0.037262727, 0.001156667, 
    0.024461299, 0.026203592, 0.031913077, 0.040168571, 0.035235902, 
    0.019156667, 0.04172913, 0.03591233, 0.026405094, 0.019256055, 
    0.011310755, 0.000412414), ymax = c(0.268973856, 0.219709677, 
    0.158936508, 0.343307692, 0.205225352, 0.068857143, 0.06059596, 
    0.047296296, 0.002559633, 0.032446541, 0.029476821, 0.0394, 
    0.048959184, 0.046833333, 0.047666667, 0.044269231, 0.051, 
    0.029181818, 0.03052381, 0.026892857, 0.001511628), ymean = c(0.231733739333333, 
    0.204891473333333, 0.140787890333333, 0.295301559666667, 
    0.173604191666667, 0.057967681, 0.058076578, 0.043017856, 
    0.00141152033333333, 0.0274970166666667, 0.0273799226666667, 
    0.0357511486666667, 0.0442377366666667, 0.0409452846666667, 
    0.0298284603333333, 0.042549019, 0.0407020586666667, 0.0272998796666667, 
    0.023900407, 0.016336106, 0.000488014)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -21L), .Names = c("id", 
"var", "ymin", "ymax", "ymean"))

3 个答案:

答案 0 :(得分:2)

由于@Miff has written 条在对数刻度上通常没用。通过条形图,我们将条形的高度相互比较。要做到这一点,我们需要一个固定点来比较,通常是0,但log(0)是负无穷大。

所以,我强烈建议您考虑使用geom_point()而不是geom_bar()。即,

ggplot(df, aes(x=id, y=ymean , color=var)) +
  geom_point(position=position_dodge(.7))+
  scale_y_log10("y",
                breaks = trans_breaks("log10", function(x) 10^x),
                labels = trans_format("log10", math_format(10^.x)))+
  geom_errorbar(aes(ymin=ymin,ymax=ymax),
                size=.25,   
                width=.07,
                position=position_dodge(.7))+
  theme_bw()

dot plots are better than bars with log scale

如果你真的非常想要酒吧,那么你应该使用geom_rect而不是geom_bar并设置你自己的基线。也就是说,geom_bar的基线为零,但您必须以对数比例创建新基线。您的Plot 1似乎使用10 ^ -7。

这可以通过以下方式实现,但同样,我认为这是一个非常糟糕的主意。

ggplot(df, aes(xmin=as.numeric(id)-.4,xmax=as.numeric(id)+.4, x=id, ymin=10E-7, ymax=ymean, fill=var)) +
  geom_rect(position=position_dodge(.8))+
  scale_y_log10("y",
                breaks = trans_breaks("log10", function(x) 10^x),
                labels = trans_format("log10", math_format(10^.x)))+
  geom_errorbar(aes(ymin=ymin,ymax=ymax),
                size=.25,   
                width=.07,
                position=position_dodge(.8))+
  theme_bw()

Really bad idea of how to have a barplot with a log scale

答案 1 :(得分:1)

如果您需要翻转条形图,可以计算自己的log10(y),请参阅示例:

library(ggplot2)
library(dplyr)

# make your own log10
dfPlot <- df %>% 
  mutate(ymin = -log10(ymin),
         ymax = -log10(ymax),
         ymean = -log10(ymean))

# then plot
ggplot(dfPlot, aes(x = id, y = ymean, fill = var, group = var)) +
  geom_bar(position = "dodge", stat = "identity",
           width = 0.7,
           size = 0.9)+
  geom_errorbar(aes(ymin = ymin, ymax = ymax),
                size = 0.25,   
                width = 0.07,
                position = position_dodge(0.7)) +
  scale_y_continuous(name = expression(-log[10](italic(ymean)))) + 
  theme_bw() 

enter image description here

答案 2 :(得分:1)

首先,不要这样做! ?geom_bar的帮助文件说:

  

条形图使用高度来表示一个值,因此它的基数   必须始终显示条形以产生有效的视觉比较。娜奥米   罗宾斯有一个很好的article on this topic。这就是为什么它没有   使用带有条形图的对数缩放y轴的意义。

举一个具体的例子,以下是一种产生你想要的图形的方法,但是更大的k也是正确的但是在视觉上产生不同的图形。

k<- 10000  

ggplot(df, aes(x=id, y=ymean*k , fill=var, group=var)) +
  geom_bar(position="dodge", stat="identity",
           width = 0.7,
           size=.9)+
  geom_errorbar(aes(ymin=ymin*k,ymax=ymax*k),
                size=.25,   
                width=.07,
                position=position_dodge(.7))+
  theme_bw() + scale_y_log10(labels=function(x)x/k)

K = 1E4

Plot when k=1e4

K = 1E6

enter image description here