Search code examples
rplotlyrgbascatter3d

plotly 3d scatter plot with solid and transparent colors in R


I'm trying to create a 3d scatter plot with plotly in R. I want to color the data points by a categorical value, using a custom color scale. I need some of the values to be solid colors and others to be transparent. Here is a mockup of my code:

mtcars$brand <- sapply(strsplit(rownames(mtcars), " "), "[[", 1)
mtcars$brand <- as.factor(mtcars$brand)

custom_colors <- c("#ebac23", "#b80058", "#008cf9", "#006e00", "#00bbad"
                 , "#d163e6", "#b24502", "#ff9287", "#5954d6", "#00c6f8"
                 , "#878500", "#00a76c", "#bdbdbd", "#846b54", "#5F2F87"
                 , "#241346", "#B3EE3A", "#077187", "#FFE06A", "#73787E"
                 , "#A6CEE3", "#1F78B4")
fig <- plot_ly(mtcars, x = ~wt, y = ~hp, z = ~qsec, color = ~brand
             , colors = custom_colors, type = "scatter3d", mode = "markers")
fig <- fig %>% add_markers()

fig

What I would need is i.e: to color "Cadillac" and "Ferrari" with a transparent color, and all the other brands with solid colors. I've tried using two traces, one with the transparent colors and one with the solid ones, and transforming all my colors into rgba. However that does not work as intended, since it just colors the points by trace and not by each individual brand. The only solution I can think of is adding each brand as a trace, but there has to be a simpler way of doing it, right...

RIGHT???


Solution

  • The following code allows you to select the transparancy level for the factors of your choice.

    I directly assigned the color and opacity level to each car model.

    ### Import libraries
    library(plotly)
    library(dplyr)
    
    ### Import data
    data(mtcars)
    mtcars$brand <- sapply(strsplit(rownames(mtcars), " "), "[[", 1)
    mtcars$brand <- as.factor(mtcars$brand)
    mtcars <- mtcars[order(mtcars$brand), ]
    
    # Set opacity
    mtcars$custom_opacity <- ifelse(mtcars$brand %in% c("Lincoln", "Cadillac"), 0.5, 1)
    
    # Set colors
    mtcars$custom_colors <- c("#ebac23", "#b80058", "#008cf9", 
                              "#006e00", "#00bbad", "#d163e6", 
                              "#b24502", "#ff9287", "#5954d6", 
                              "#00c6f8", "#878500", "#00a76c", 
                              "#bdbdbd", "#846b54", "#5F2F87", 
                              "#241346", "#B3EE3A", "#077187", 
                              "#FFE06A", "#73787E", "#A6CEE3", 
                              "#1F78B4", "#B3EE3A", "#077187", 
                              "#FFE06A", "#73787E", "#A6CEE3", 
                              "#1F78B4", "#FFE06A", "#73787E", 
                              "#A6CEE3", "#1F78B4")
    
    #### Display plot
    fig <- plot_ly(mtcars, x = ~wt, y = ~hp, z = ~qsec, 
                   color = ~mtcars$brand, 
                   colors = mtcars$custom_colors, 
                   opacity = mtcars$custom_opacity, 
                   type = "scatter3d", 
                   mode = "markers")
    
    fig <- fig %>% add_markers()
    
    fig
    

    enter image description here

    As you can see, our two labels Lincoln and Cadillac are transparant (though it was Ferrari in your question).