Black Lives Matter. Please consider donating to Black Girls Code today.

How do I map categorical variables to color the outline of points in a 3D scatter plot in R Plotly?

This is a repost of this stackoverflow question which has seen only one answer in three weeks, telling me I can’t do what I want to do: https://stackoverflow.com/questions/60664020/how-do-i-map-categorical-variables-to-color-the-outline-of-points-in-a-3d-scatte

Was hoping I could get some insight here on the main plotly forum.


This code makes a simple 3d scatter plot of the Fisher iris dataset, with an additional categorical variable added:


library(plotly)
roots <- factor(round(runif(n = dim(iris)[2],min = -.499,max = 2.499)))
my_iris <- cbind(data.frame(roots), iris)


plot_ly() %>%
  add_trace(data = my_iris, type = 'scatter3d', mode = "markers",
            x = ~Sepal.Length,
            y = ~Petal.Length,
            z = ~Sepal.Width, 
            color = ~Species,
            colors = c("red","blue","green")
            
  )


By looking at this help page: https://plot.ly/r/marker-style/

I was able to figure out that you can add an outline to the points like this:

plot_ly() %>%
  add_trace(data = my_iris, type = 'scatter3d', mode = "markers",
            x = ~Sepal.Length,
            y = ~Petal.Length,
            z = ~Sepal.Width, 
            color = ~Species,
            colors = c("#00FA9A34","#B22222dd","#00BFFFee"),
            marker = list(
              
              line = list(
                color = "#aabbffdd",
                width = 2
              )
              
            )
  )

Looking at this site https://plot.ly/r/reference/#scatter3d made the idea that lines are a property of scatter3d markers that in turn have the properties color and width make sense.

Now I attempt to map colors to the outlines based on my new roots variable,

plot_ly() %>%
  add_trace(data = my_iris, type = 'scatter3d', mode = "markers",
            x = ~Sepal.Length,
            y = ~Petal.Length,
            z = ~Sepal.Width,
            color = ~Species,
            colors = c("#00FA9A34","#B22222dd","#00BFFF66"),
            marker = list(
             
              line = list(
                color = ~roots,
                colors = c("#000000ff","#f00f3355","#dd22ccbb"),
                width = 2
              )
              
            )
  )

and it doesn’t quite work: The first hex+alpha value I use should map to completely opaque black, but that is not one of the colors I get, and I would expect to see legend entries that describe the output.

So my question is: is there a way to do this aesthetic mapping? Perhaps instead of using add_trace I should use add_markers? Is there a way to do this in 2d scatters in Plotly R? Also would appreciate hints on how to learn Plotly for R properly as the documentation page I linked to above is a bit opaque and there seem to be fewer great resources to learn plotly than there are for ggplot2.

Writing this question was sort of like a ‘rubber duck debugging’ session where I came up with my own answer (https://stackoverflow.com/a/61073517/5879985), but now I have a follow up question which I will post as it’s own topic.