M. Beausoleil
M. Beausoleil

Reputation: 3555

Setting colours in plotly R is not working (factors) in add markers

I'm trying to set the colour in R for "points" or markers in plotly with a custom palette. It doesn't work. I'm also trying to add a title to the graph, but it won't appear. In addition, I'd like to remove some elements of the legend (like the extra "z") and add a title to the legend elements. Nothing seems to work, even if it is present in the code.

library(plotly)
library(tidyverse)
set.seed(123456)
pal <- c("black", "orange", "darkgreen", "pink")
pal <- setNames(pal, levels(as.factor(c("gr1","gr2","gr3","gr4"))))

linedat = data.frame(x = rep(mean(1:50),2),
                         y = rep(mean(1:50),2),
                         z = c(0,1))

zoom = 3
pg = plotly::plot_ly(x = 1:50, 
                     y = 1:50, 
                     z = outer(1:50,1:50,"+")/100) %>% 
  add_surface(contours = list(
    z = list(show = TRUE, start = 0, end = 1, size = 0.05)), 
    opacity = 1) %>%  
  add_markers(x = rnorm(50,25,5),
              y = rnorm(50,25,5),
              marker = list(opacity = 0.9),
              type="scatter3d",
              mode = "markers",inherit = FALSE,
              colors = pal,
              color = as.factor(sample(1:4,50,replace = T)),
              z = rbinom(50,1,.5)) %>% 
  layout(scene=list(title = "Title won't show up????", 
                    xaxis = list(title = 'trait1'), 
                    yaxis = list(title = 'trait1',autorange = "reversed"), 
                    camera = list(eye = list(x = cos(0.8*pi)*zoom, y = sin(pi*1.3)*zoom, z= 2.00)),
                    legend = list(title=list(text='<b> Groups </b>')))) %>% 
  add_trace(data=linedat, x=~x, y=~y, z=~z,
            type="scatter3d", mode="lines", 
            line = list(color = pal[1], 
                        width = 14),name = "Avg. data1")%>% 
  add_trace(data=linedat, x=~x+20, y=~y+20, z=~z, 
            type="scatter3d", mode="lines", 
            line = list(color = pal[4], 
                        width = 14),name = "Avg. data2")
pg

enter image description here

See how here I'm able to set the colour of the points, but I'm not able to get the names of the colours to show in the legend (I modified the code to match what @Kat suggested):

library(plotly)
library(tidyverse)
set.seed(123456)
pal <- c("black", "orange", "darkgreen", "pink")
pal <- setNames(pal, levels(as.factor(c("gr1","gr2","gr3","gr4"))))

linedat = data.frame(x = rep(mean(1:50),2),
                         y = rep(mean(1:50),2),
                         z = c(0,1))

zoom = 3
pg = plotly::plot_ly(x = 1:50, 
                     y = 1:50, 
                     z = outer(1:50,1:50,"+")/100) %>% 
  add_surface(contours = list(
    z = list(show = TRUE, start = 0, end = 1, size = 0.05)), 
    opacity = 1, colorbar = list(title = "Only one Z")) %>%  
  add_markers(x = rnorm(50,25,5),
              y = rnorm(50,25,5),
              marker = list(color = pal[as.factor(sample(1:4,50,replace = T))],opacity = 0.9),
              type="scatter3d",
              mode = "markers",inherit = FALSE,
              colors = pal,
              
              z = rbinom(50,1,.5)) %>% 
  layout(title = "Title that won't show",
         margin = list(t = 40),
         legend = list(title = list(
           text = "<br>Legends deserve names, too")),
         scene=list(xaxis = list(title = 'trait1'), 
                    yaxis = list(title = 'trait1',autorange = "reversed"), 
                    camera = list(eye = list(x = cos(0.8*pi)*zoom, 
                                             y = sin(pi*1.3)*zoom, z= 2.00)))) %>% 
  add_trace(data=linedat, x=~x, y=~y, z=~z,
            type="scatter3d", mode="lines", 
            line = list(color = pal[1], 
                        width = 14),name = "Avg. data1")%>% 
  add_trace(data=linedat, x=~x+20, y=~y+20, z=~z, 
            type="scatter3d", mode="lines", 
            line = list(color = pal[4], 
                        width = 14),name = "Avg. data2");pg

enter image description here

Upvotes: 1

Views: 939

Answers (1)

Kat
Kat

Reputation: 18714

Your original plot_ly call and add_trace calls can remain as is. I've included the changes needed for the layout call and added the call needed for colorbar.

The layout first.

layout(title = "Title that won't show",       # <------ give my plot a name
         margin = list(t = 40),                 # don't smash that title, either
         legend = list(title = list(
           text = "<br>Legends deserve names, too")), # <--- name my legend
         scene=list(title = "Title won't show up????", # <- this can go away
                    xaxis = list(title = 'trait1'), 
                    yaxis = list(title = 'trait1',autorange = "reversed"), 
                    camera = list(eye = list(x = cos(0.8*pi)*zoom, 
                                             y = sin(pi*1.3)*zoom, z= 2.00)),
                    legend = list(title=list(text='<b> Groups </b>')))) %>% 
  colorbar(title = "Only one Z")          # <--- give me one z colorbar title

enter image description here

(Some colors are different in the image; I didn't realize I had the pal object...sigh)



Update

This addresses your additional questions.

First, I'm not getting an error from the method in which I title the color bar. You'll have to share what error you're getting.

I didn't realize that it was ignoring the colors you set in markers, either. The easiest way to address this is to call that trace first. Since nothing else was declared within markers, I called opacity outside of the list, but it's fine the way you have it.

First, I commented out the setNames call, because that won't work for the marker's trace and it doesn't matter to the other traces.

library(plotly)

set.seed(123456)
pal <- c("black", "orange", "darkgreen", "pink")
# pal <- setNames(pal, levels(as.factor(c("gr1","gr2","gr3","gr4")))) 

linedat = data.frame(x = rep(mean(1:50),2),
                     y = rep(mean(1:50),2),
                     z = c(0,1))
zoom = 3

I made plot_ly() empty and put all the data for the surface in that trace. I also added inherit = false so that the layout could go at the end without the data errors.

set.seed(123456)
pg = plotly::plot_ly() %>% 
  add_trace(inherit = F,
            x = rnorm(50,25,5),
            y = rnorm(50,25,5),
            type="scatter3d",
            mode = "markers",
            opacity = .8,
            colors = pal,
            color = as.factor(sample(1:4, 50, replace = T)),
            z = rbinom(50,1,.5)) %>% 
  add_surface(x = 1:50, 
              y = 1:50, 
              z = outer(1:50,1:50,"+")/100,
              colorscale = "Viridis",
              contours = list(
                z = list(show = TRUE, start = 0, end = 1, size = 0.05)), 
              opacity = 1) %>%  
  add_trace(data=linedat, x=~x, y=~y, z=~z,
            type="scatter3d", mode="lines", 
            line = list(color = pal[1], 
                        width = 14),name = "Avg. data1", inherit = F) %>% 
  add_trace(data=linedat, x=~x+20, y=~y+20, z=~z, 
            type="scatter3d", mode="lines", 
            line = list(color = pal[4], 
                        width = 14),name = "Avg. data2", inherit = F) %>%

The last part is the layout, but this is not different than my original answer.

  layout(title = "Title that won't show",       # <------ give my plot a name!
         margin = list(t = 40),                 # don't smash that title, either
         legend = list(title = list(
           text = "<br>Legends deserve names, too"),
           tracegroupgap = 350), # <--- name my legend!
         scene=list(title = "Title won't show up????",   # <--- this can go away!
                    xaxis = list(title = 'trait1'), 
                    yaxis = list(title = 'trait1',autorange = "reversed"), 
                    camera = list(eye = list(x = cos(0.8*pi)*zoom, 
                                             y = sin(pi*1.3)*zoom, z= 2.00)),
                    legend = list(title=list(text='<b> Groups </b>')))) %>% 
  
  colorbar(title = "Only one Z")      # <--- give me one z for the title!
pg

enter image description here

Upvotes: 1

Related Questions