Search code examples
rplotlycolorbarerrorbar

How do you make plotly error bars follow a colorscale?


Let me start by saying I have tried the methods outlined in Color coding error bars in a plotly scatter plot, but I have not been able to get them to work. From what I can tell there were changes in how coloraxes are treated in plotly version 4, which might be why this no longer solves the problem.

I want to make a simple scatterplot of two variables with error bars for each variable. I would like the color of the points and their error bars to follow a scale determined by a third variable. I have been unable to make the error bar colors match the markers. Below are a couple simple methods I tried and their results.

set.seed(1)
x.data <- rnorm(20, 0, 1)
y.data <- rnorm(20, 2, 1)
x.err <- runif(20, 0.2, 0.8)
y.err <- runif(20, 0.2, 0.8)
z.data <- runif(20, 1.7, 2.8)

p <- plot_ly() %>%
  add_markers(x=x.data, y=y.data,
              error_x=list(array=x.err, color=z.data),
              error_y=list(array=y.err, color=z.data),
              marker=list(color=z.data, colorscale='Viridis',
                          colorbar=list(title='Z', limits=range(z.data)))) %>%
  layout(xaxis=list(title='X'), yaxis=list(title='Y'))

enter image description here

z.norm <- (z.data - min(z.data))/(max(z.data)-min(z.data))
mycramp<-colorRamp(c("darkblue","yellow"))
mycolors<-rgb(mycramp(z.norm), maxColorValue = 255)

p <- plot_ly() %>%
  add_markers(x=x.data, y=y.data,
              error_x=list(array=x.err, color=mycolors),
              error_y=list(array=y.err, color=mycolors),
              marker=list(color=mycolors,
                          colorbar=list(title='Z', limits=range(z.data)))) %>%
  layout(xaxis=list(title='X'), yaxis=list(title='Y'))

Bad color bars


Solution

  • The documentation on r plotly can be a bit lacking. I think this is what you're looking for though. You want to use the name argument. Both color and name have to be included. We have to define the name argument's levels manually. We can set color to factor as well but then we lose the color ramp. colors let's us change the color palette using RColorBrewer palettes.

    plot_ly() %>%
      add_markers(x = x.data, 
                  y = y.data, 
                  showlegend = F, # must hide legend here or it shows up twice
                  name = factor(z.data, levels = z.data, labels = z.data), # this is missing
                  color = z.data, 
                  colors = "Set1", 
                  error_x = list(array = x.err),
                  error_y = list(array = y.err))
    

    enter image description here