Skip to content

single legend for multiple traces / share legend across subplots / disable automatic mapping of fill, color, etc #800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rubenalv opened this issue Jul 22, 2017 · 3 comments

Comments

@rubenalv
Copy link

Hello,
I am not sure whether this is a bug or a feature to request, perhaps it's in between.

the problems: mapping of data to the legend seems automatic and cannot be disabled. If traces share names (I think) they should be plotted with a unique legend name and not with one name per trace, repeating the names.

example:
I have a plot with a legend with two elements: 'name': 'trace1' and 'name':'trace2' but four actual traces, which I divide in two groups by marker symbol. The result is a plot per trace (correct), mapping of legend to both color and symbol (not desired), and repeated trace names in the legend (I would like the trace names to show as unique names).

expected behaviour: No automatic mapping, the user can decide whether to map or not (e.g. ggplot2 from R does this. E.g. with 'color', if it is within an aesthetic group it's mapped, but when it is outside that group it is fixed and does not appear in the legend). Since two traces share a name, they should be mapped to a single name in the legend, and when clicking on that name both traces should get hidden.

suggested workarounds: Hide some legend names. However this is not good, because if the legend is hidden the traces cannot be accessed from it. I expect that a unique legend name controls more than one trace in the plot.

example code:

import plotly.offline as pyoff

dataplot = [
  dict(
   name = 'trace1',
   x = [1,2,3,4],
   y = [1,1,1,1],
   mode = 'markers',
   marker = {'symbol':'circle'}),
  dict(
   name = 'trace2',
   x = [1,2,3,4],
   y = [2,2,2,2],
   mode = 'markers',
   marker = {'symbol':'circle'}),
  dict(
   name = 'trace1',
   x = [1,2,3,4],
   y = [3,3,3,3],
   mode = 'markers',
   marker = {'symbol':'square'}),
  dict(
   name = 'trace2',
   x = [1,2,3,4],
   y = [4,4,4,4],
   mode = 'markers',
   marker = {'symbol':'square'})
  ]

pyoff.plot(dict(data = dataplot))
   

Thank you very much for all contributions, I wished I knew enough to help myself!

@rubenalv
Copy link
Author

rubenalv commented Jul 22, 2017

Actually, the behaviour I want can be obtained by overriding mapping manually (I think I am too used to R and it's mapping), and using a combination of legendgroup and showlegend = False.
This example works for both multiple traces in a single plot, and for traces with shared legends across subplots. Hope this can help others.

Code below:

#!bin/python3

from plotly import tools
import plotly.offline as pyoff

dataplot = [
  dict(
    name = 'trace1',
    legendgroup = 'a',
    x = [1,2,3,4],
    y = [1,1,1,1],
    mode = 'markers',
    marker = {'symbol':'circle', 'color':'orange'}),
  dict(
    name = 'trace2',
    legendgroup = 'b',
    x = [1,2,3,4],
    y = [2,2,2,2],
    mode = 'markers',
    marker = {'symbol':'circle', 'color': 'steelblue'}),
  dict(
    name = 'trace1',
    legendgroup = 'a',
    showlegend = False,
    x = [1,2,3,4],
    y = [3,3,3,3],
    mode = 'markers',
    marker = {'symbol':'square', 'color':'orange'}),
  dict(
    name = 'trace2',
    legendgroup = 'b',
    showlegend = False,
    x = [1,2,3,4],
    y = [4,4,4,4],
    mode = 'markers',
    marker = {'symbol':'square', 'color':'steelblue'})
  ]

pyoff.plot(dict(data = dataplot))

# -----------------
# same with subplots

trace1a = dict(
   name = 'trace1',
   legendgroup = 'a',
   x = [1,2,3,4],
   y = [1,1,1,1],
   mode = 'markers',
   marker = {'symbol':'circle', 'color':'orange'})
trace1b = dict(
   name = 'trace2',
   legendgroup = 'b',
   x = [1,2,3,4],
   y = [2,2,2,2],
   mode = 'markers',
   marker = {'symbol':'circle', 'color': 'steelblue'})

trace2a = dict(
   name = 'trace1',
   legendgroup = 'a',
   showlegend = False,
   x = [1,2,3,4],
   y = [3,3,3,3],
   mode = 'markers',
   marker = {'symbol':'square', 'color':'orange'})
trace2b = dict(
   name = 'trace2',
   legendgroup = 'b',
   showlegend = False,
   x = [1,2,3,4],
   y = [4,4,4,4],
   mode = 'markers',
   marker = {'symbol':'square', 'color':'steelblue'})


fig = tools.make_subplots(rows=1, cols=2)
fig.append_trace(trace1a, 1, 1)
fig.append_trace(trace1b, 1, 1)
fig.append_trace(trace2a, 1, 2)
fig.append_trace(trace2b, 1, 2)

pyoff.plot(fig)
   

@rubenalv rubenalv changed the title disable automatic mapping of legends to symbol, fill, color, etc single legend for multiple traces / share legend across subplots / disable automatic mapping of fill, color, etc Jul 22, 2017
@mwouts
Copy link

mwouts commented Jun 19, 2018

Thanks for reporting. I also use the manual mapping as you document, as I found no other way, but I feel it's a bit too low level. I've open cf. plotly/plotly.js#2744 to see if we can get a better way.

@sorenwacker
Copy link

The problem here is not all classes might appear in all subplots. If you chose a subplot for the legend that has not all classes then the missing ones will not show up in the legend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants