Transform y axis in bar plot using scale_y_log10()

前端 未结 3 2172
野性不改
野性不改 2020-12-22 10:13

Using the data.frame below, I want to have a bar plot with y axis log transformed.

I got this plot

using this code

ggplot(df, aes(x=         


        
相关标签:
3条回答
  • 2020-12-22 10:26

    If you need bars flipped, maybe calculate your own log10(y), see example:

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

    0 讨论(0)
  • 2020-12-22 10:37

    Firstly, don't do it! The help file from ?geom_bar says:

    A bar chart uses height to represent a value, and so the base of the bar must always be shown to produce a valid visual comparison. Naomi Robbins has a nice article on this topic. This is why it doesn't make sense to use a log-scaled y axis with a bar chart.

    To give a concrete example, the following is a way of producing the graph you want, but a larger k will also be correct but produce a different plot visually.

    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

    k=1e6

    0 讨论(0)
  • 2020-12-22 10:38

    As @Miff has written bars are generally not useful on a log scale. With barplots, we compare the height of the bars to one another. To do this, we need a fixed point from which to compare, usually 0, but log(0) is negative infinity.

    So, I would strongly suggest that you consider using geom_point() instead of geom_bar(). I.e.,

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

    If you really, really want bars, then you should use geom_rect instead of geom_bar and set your own baseline. That is, the baseline for geom_bar is zero but you will have to invent a new baseline in a log scale. Your Plot 1 seems to use 10^-7.

    This can be accomplished with the following, but again, I consider this a really bad idea.

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

    0 讨论(0)
提交回复
热议问题