1

I have a plot and I would only like to render the legend but none of the plot points. Can anyone tell me how to do this?

library(tidyverse)
library(plotly)

mtcars %>% 
  mutate(cyl = factor(cyl)) %>% 
  plot_ly() %>% 
  add_markers(x = ~mpg,
              y = ~hp,
              color = ~cyl,
              colors = c("4" = "red", "6" = "green", "8" = "blue"))

Currently I have this:

enter image description here

What I want is this:

enter image description here

ismirsehregal
  • 30,045
  • 5
  • 31
  • 78
DJC
  • 1,491
  • 6
  • 19
  • Please check out the [documentation](https://plotly.com/python/legend/), `fig.add_trace(go.Scatter( x=[1, 2, 3, 4, 5], y=[5, 4, 3, 2, 1], visible='legendonly' ))`. Did you try setting the visibility to legendonly? Can you state in the question what you tried and why it isnt working? – Annet Nov 16 '21 at 16:26
  • Thank you Annet. I wasn't aware of visible = legendonly. This helps the plot initialize without the points showing, but when you click the individual legend entries, which start out faded as the points are deselected, then points then appear. I need the legend to appear as normal, not faded out, and no points to appear when the user clicks it. – DJC Nov 16 '21 at 16:31
  • Oke that makes things a bit clearer. Specific reason you want to use plotly rather than ggplot? See https://stackoverflow.com/questions/52703489/draw-a-legend-to-an-empty-ggplot or https://stackoverflow.com/questions/12041042/how-to-plot-just-the-legends-in-ggplot2 Although you can transform ggplots to plotly, but I dont know if it would work in your example. – Annet Nov 16 '21 at 16:46
  • Honestly the dev. version of these plots were all built in ggplot and then wrapped with a ggplotly wrapper to make them interactive. For prod. my preference is build everything with native plotly code, rather than using the wrapper as I find that easier for debugging – DJC Nov 16 '21 at 16:48
  • Hahah, the "you shouldnt use R for prod anyway" isn't probably not what you want to hear :). Which ofcourse doesn't really make sense in this case as you would have the same problem in python plotly. As I am not anymore proficient in plotly I hope someone comes along knowing the answer. – Annet Nov 16 '21 at 16:53
  • Fair. This is for a Shiny app which is one of the use few use cases for R in prod me thinks :) – DJC Nov 16 '21 at 16:54
  • 1
    Can I send you to the data engineers I am working with? We would love if someone successed to tell them that we need shiny! – Annet Nov 16 '21 at 17:12
  • 1
    May I ask what is the background here? What are you doing with the result? – ismirsehregal Nov 19 '21 at 11:51
  • 1
    Haha I'm a Shiny fan so always happy to make a plug for it :) Specific use case is business-specific, but is complex chart in which markers can be colored and shaped according to two categorical variables. If you don't find a wonky hack, then the legend will show all combinations of these two categorical variables (so if you have 5 X 2, then you have 10 legend entries) where in-fact all I want is a legend with 7 entries (5 + 2) – DJC Nov 19 '21 at 18:11
  • 1
    Ah, this could also be solved using `legendgroup`'s. Please check my related answers [here](https://stackoverflow.com/questions/67901422/how-to-use-multiple-groups-in-plotly-but-only-a-defined-number-of-legendgroups/67902979#67902979) or [here](https://stackoverflow.com/questions/63627563/merging-legends-in-plotly-subplot/63629831#63629831). – ismirsehregal Nov 19 '21 at 18:17

1 Answers1

2

Not sure what this result should be good for, but you can disable legendclick's like this:

Edit: also possible without onRender

library(plotly)
mtcars %>% 
  mutate(cyl = factor(cyl)) %>% 
  plot_ly() %>% 
  add_markers(x = ~mpg,
              y = ~hp,
              color = ~cyl,
              colors = c("4" = "red", "6" = "green", "8" = "blue"), visible='legendonly') %>%
  layout(legend=list(itemclick = FALSE, itemdoubleclick = FALSE)) 

library(htmlwidgets)
library(plotly)

js <- c(
  "function(el, x){",
  "  el.on('plotly_legendclick', function() {",
  "    return false;",
  "  });",
  "  el.on('plotly_legenddoubleclick', function() {",
  "    return false;",
  "  });",
  "}")

mtcars %>% 
  mutate(cyl = factor(cyl)) %>% 
  plot_ly() %>% 
  add_markers(x = ~mpg,
              y = ~hp,
              color = ~cyl,
              colors = c("4" = "red", "6" = "green", "8" = "blue"), visible='legendonly') %>%
  onRender(js)
ismirsehregal
  • 30,045
  • 5
  • 31
  • 78