shosaco shosaco - 1 year ago 80
R Question

colors in Plotly 4.x for R

I use the new Plotly (4.x) package for R with Shiny. I am colouring my graphs categorically, and if there is only 1 item in a category, the colouring exits with an error. A minimal example would be as follows:

plot_ly(head(iris, 1),
x = ~Sepal.Length, y = ~Sepal.Width, color=~Species,
colors = setNames("#FF5748", "setosa"),
type = "scatter", mode = "markers")

Error in if (has_attr(x$type, "colorscale")) x[["z"]] else NULL : argument is of length zero

vector is my named vector, where names refer to Species and the appropriate colour is chosen, always correct if more than one item per Species is present, e.g.:

x=~Sepal.Length, y=~Sepal.Width, color=~Species,
colors=setNames(c("#FF5748", "black"), c("setosa", "versicolor")),
type="scatter", mode="markers")

Is this a plotly bug or am I missing something?


edit: to be more precise, this problem occurs often when generating subplots and the a subplot has only 1 datapoint:

colormap <- setNames(c("#FF5748", "black"), c("setosa", "versicolor"))
data <- iris[c(1,2,60), ]

# vars contains the facet variables
vars <- levels(factor(data$Species))

# build a list of length(var) plots
plots <- lapply(vars, function(species) {
data <- subset(data, Species==species)
plot_ly(data, x=~Sepal.Length, y=~Sepal.Width) %>%
add_bars(color=~Species, colors=colormap)

p <- subplot(plots, nrows = length(plots), shareX = TRUE, titleX = FALSE)

This code produces the error, while using
color = factor(data$Species)
works fine. Thanks dww!

dww dww
Answer Source

I can confirm replicating this issue. It occurs when

  1. the data has only one row,
  2. and a color = argument is passed to plot_ly or add_trace.
  3. and the column used for color has factor levels that are not present

We can see that the 3rd of these criteria is needed to replicate the bug, as this gives an error:

pdata = head(iris, 1)
plot_ly(pdata, x = ~Sepal.Length, y = ~Sepal.Width,
          color = pdata$Species,
          colors = setNames("#FF5748", "setosa"),
          type = "scatter", mode = "markers")

But this does not:

plot_ly(pdata, x = ~Sepal.Length, y = ~Sepal.Width, 
         color = factor(pdata$Species),      
         colors = setNames("#FF5748", "setosa"),
         type = "scatter", mode = "markers")

This looks like a bug. For the moment, you can sidestep the issue using the 2nd structure above that refactors your color column. Note that you will need to use $ notation rather than ~ to reference the column.