1

I'm trying to display a bar chart with error bars. When I add a color variable, the error bars are displayed on the wrong bars.

df <- data_frame(label = c("Step 1", "Step 2", "Step 3", "Step 4"), 
             Action = c("DISPENSE", "WAIT", "DISPENSE", "WAIT" ), 
             Avg = c(1.65, 3.88, 1.19, 23.09),
             StdDev = c(0.80, 7.54, 0.11, 14.63)) 

p1 <- plot_ly(df, type = "bar", orientation = 'h', 
    y = ~label, x = ~Avg, color = ~Action,
    error_x = list(type = "data", array = ~StdDev, color = "#000000"),
    text = ~paste0(Avg," (+/- ",StdDev,")"), hoverinfo = "text")

p2 <- plot_ly(df, type = "bar", orientation = 'h', 
    y = ~label, x = ~Avg,
    error_x = list(type = "data", array = ~StdDev, color = "#000000"),
    text = ~paste0(Avg," (+/- ",StdDev,")"), hoverinfo = "text")

subplot(p1, p2, nrows=2)

this is the output of the plot:

Plot output image

I want the chart to be colored by Action, like in p1, but with the error bars correctly assigned for each row, like in p2.

I've tried various forms for the error_x parameters, without success:

error_x = ~list(type = "data", array = StdDev, color = "#000000")
error_x = ~list(type = "array", array = StdDev, color = "#000000")
error_x = list(type = "array", array = ~StdDev, color = "#000000")

I suspect it's similar to this problem, or they're both caused by the same bug. I wasn't able to implement their solutions.

Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
J.Mars
  • 11
  • 2

1 Answers1

0

Passing an array to color causes more changes than just having colored bars, it also splits the data in multiple traces.

If you want both, different colors and different traces, I don't see any other solution except for creating the traces manually.

In the first graph the colors are assigned manually, in the 2nd graph for each unique Action value a new trace is created.

library(tibble)
library(plyr)
library(plotly)

df <- data_frame(label = c("Step 1", "Step 2", "Step 3", "Step 4"), 
                 Action = c("DISPENSE", "WAIT", "DISPENSE", "WAIT" ), 
                 Avg = c(1.65, 3.88, 1.19, 23.09),
                 StdDev = c(0.80, 7.54, 0.11, 14.63)) 

color_choices <- list("#8DA0CB", "#59C5A3")
colors <- mapvalues(df$Action, unique(df$Action), color_choices)
p1 <- plot_ly(df, type = "bar", orientation = 'h', 
              y = ~label, x = ~Avg,
              error_x = list(type = "data", array = ~StdDev),
              text = ~paste0(Avg," (+/- ",StdDev,")"), hoverinfo = "text",
              marker = list(color = colors))

p2 <- plot_ly()
names(color_choices) <- unique(df$Action)

for (action in unique(df$Action))
{
  df_filtered <- filter(df, Action == action)
  p2 <- plotly::add_bars(p2, orientation = 'h',
                         y = df_filtered$label, x = df_filtered$Avg,
                         error_x = list(type = "data", array = df_filtered$StdDev), 
                         text = ~paste0(df_filtered$Avg," (+/- ", df_filtered$StdDev, ")"),
                         color = color_choices[action][[1]],
                         hoverinfo = "text",
                         name = action)

}
subplot(p1, p2, nrows=2)

enter image description here

Maximilian Peters
  • 30,348
  • 12
  • 86
  • 99