Search code examples
rggplot2plotlyggplotly

ggplotly - only show the top whisker of an errorbar


I have a ggplot barplot with an errorbar, which I'm putting through ggplotly. My preference is to only show the top of the errorbar. In ggplot2, I simply specify the y_min of the errorbar to be the value of the bar, and plot the errorbar first, so that the bottom whisker is hidden behind the geom_bar. However, once I run the plot through ggplotly, the errorbar is shown on the top. Is there a way to not show the bottom whisker? I searched for ways to change the order of the 2 traces, or options for "top-only" errorbars, but couldn't find anything.

library(dplyr)
library(ggplot2)
library(plotly)

df <- data.frame(y = c(5, 10), group = c("a", "b"))
p <- ggplot(df) +
        geom_errorbar(aes(x = group, ymin = y, ymax = y + 10), linewidth = 0.1, width = 0.7) +
        geom_bar(aes(x = group, y = y), stat = "identity", fill = "lightgrey") 

# only top whisker is shown     
p 

# both top and bottom are showing
ggplotly(p) 

Solution

  • Presumably there is a way to hack the plotly object to move the error bar so that it is underneath the bars, though a simpler solution might be to draw only the objects you want visible. You can do this by drawing a zero-height errorbar at ymax and a segment between y and ymax. That way the layer order doesn't matter.

    p <- ggplot(df, aes(x = group, ymax = y + 10)) +
      geom_errorbar(aes(ymin = y + 10, ymax = y + 10), 
                    linewidth = 0.1, width = 0.7) +
      geom_linerange(aes(ymin = y), linewidth = 0.5) +
      geom_col(aes(x = group, y = y), fill = "lightgrey") 
    
    ggplotly(p) 
    

    enter image description here

    It's important to point out that the vertical line segments in either case add no information to your plot, and one could argue that having just the zero-height errorbar as a horizontal line floating above the bar might be preferable to data visualization purists.

    As a footnote, geom_col() superseded geom_bar(stat = "identity") about 8 years ago.