Skip to content
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

Support for multiple legends #1668

Closed
cpsievert opened this issue May 10, 2017 · 36 comments
Closed

Support for multiple legends #1668

cpsievert opened this issue May 10, 2017 · 36 comments
Labels
feature something new

Comments

@cpsievert
Copy link

cpsievert commented May 10, 2017

Useful when mapping multiple discrete variables to different visual aesthetics (i.e., marker.color & marker.symbol) without having to list every possible combination of levels.

Here is a ggplot2 example

qplot(data = mtcars, mpg, wt, color = factor(vs), shape = factor(am))

screen shot 2017-05-10 at 4 58 20 pm

@cpsievert cpsievert added the feature something new label May 10, 2017
@cpsievert cpsievert added this to the ggplotly parity milestone May 10, 2017
@alexcjohnson
Copy link
Collaborator

We had discussions a long time ago about an idea I was calling "legends 2.0" that would support this and many other use cases:

  • create a syntax for describing trace legend items (with modifications) within annotations
  • the legends we have today would then just be a special case of an annotation, but you could construct any arbitrary legend, or caption (symbols embedded in prose), or whatever, using this syntax.

For example, assuming the plot you've made above used one trace with variable color and symbol, its legend could be an annotation like (syntax off the top of my head... could be very different but you get the idea):

'<span style="font-size: 1.3em;">factor(vs)</span><br>' +
'&trace0{"marker.color":"red","marker.symbol":"circle"}; 0<br>' +
'&trace0{"marker.color":"green","marker.symbol":"circle"}; 1<br>' +
'<br>' +
'<span style="font-size: 1.3em;">factor(am)</span><br>' +
'&trace0{"marker.color":"black","marker.symbol":"circle"}; Automatic<br>' +
'&trace0{"marker.color":"black","marker.symbol":"triangle-up"}; Manual'

For the record, I don't know if other platforms implement a system like this but I'll note that this concept is inspired by a very similar system in Igor Pro.

@zichner

This comment has been minimized.

@Kabouik
Copy link

Kabouik commented Oct 11, 2017

Seconding this, it would be useful. On some data I'm currently working on, plotly (used in R through the corresponding package) outputs something like this:

It could be much simpler, plus it's not shown in the above picture but the factor levels are also concatenated between the two legend types being used, which is a bit ugly (it adds "()" and the spacing syntax is not correct).

@June-Skeeter
Copy link

I third this! It could be nice to be able to have legends specific to a give subplot rather than having to list all items in one legend.

@slfan2013

This comment has been minimized.

@micdonato

This comment has been minimized.

@vianamp

This comment has been minimized.

@slfan2013

This comment has been minimized.

@teddyward
Copy link

This would be great for when there are multiple y axes, so that traces are more obviously linked to the relevant y axis.

@russellromney
Copy link

This would still be really great to have for subplots and for multiple y axes.

The grouping still doesn't work as a substitute, mostly because you cannot highlight individual traces, only legend groups.

@danny305

This comment has been minimized.

@petersmp

This comment has been minimized.

@Thomas-Hirsch

This comment has been minimized.

@Braintelligence

This comment has been minimized.

@maxibor

This comment has been minimized.

@lalitsc12

This comment has been minimized.

@TolganLight

This comment has been minimized.

@JeroneGagliano
Copy link

Agree with @russellromney Having a separate legend option for each subplot is a high priority issue! Having one legend entry on the side or at the bottom of the subplots is not that helpful as they do not know which points are including in each subplot until they hover over the lines. See this example of how useful the individual legends would be.

What is the timeline for adding this? Thanks!
PlotlySubplotMultipleLegendsExample

@lalitsc12
Copy link

Agree.. as having legend on side with many plots confuses the user and also looks ugly.

@cgpu
Copy link

cgpu commented Nov 20, 2019

Agree with @russellromney Having a separate legend option for each subplot is a high priority issue! Having one legend entry on the side or at the bottom of the subplots is not that helpful as they do not know which points are including in each subplot until they hover over the lines. See this example of how useful the individual legends would be.

What is the timeline for adding this? Thanks!
PlotlySubplotMultipleLegendsExample

Very interested in this feature, so subscribing in this thread as well after the initial one here

plotly/plotly.R#1164 (comment)

@jessicajturner this might be of interest to you too.

@ttekampe
Copy link

ttekampe commented Dec 9, 2019

I am also very interested in this feature. It often makes sense to have individual legends for subplots. This feature is used a lot in other plotting libraries like for example pythons matplotlib.

@ttekampe
Copy link

I was able to solve my issue with a work around. So I wanted to store multiple plots with individual legends in a single html file and was able to do so as detailed in this stackoverflow post:

https://stackoverflow.com/questions/46821554/multiple-plotly-plots-on-1-page-without-subplot/59265030#59265030

@JeroneGagliano
Copy link

Is there an estimate of when this multiple legend enhancement will be added? Thanks!

@kevans27
Copy link

kevans27 commented Feb 7, 2020

Tacking on interest in this!

@JeroneGagliano
Copy link

I see that one could use multiple plots in the html but this gets really complicated when the chart may use one, two or three panes (depending on trend data being displayed) and the shared x-axis is great for minimizing the clutter in a multiple pane chart.

I am currently using grouped legends which is ok but does not allow the user to toggle on/off an individual line within a group. It toggles the whole group of lines on/off. Also, it is not as obvious which legend entries belong to which pane, and a side or bottom grouped legend takes up a lot of display space.

What is the level of effort for this enhancement?

Thanks
Jerone

@brian428
Copy link

Just wanted to add a +1 to this and hoping it might be addressed soon. We have complex scattergl plots where the trace points have variable symbols that have their own meaning. Being able to list the trace colors and the symbol meanings in 2 legends is something we really need.

I considered trying to stick my own custom legend underneath the Plotly legend, but since there's no way (that I know of) to control the size of the Plotly legend, this won't work because the Plotly legend could be so tall that you run out of space for a custom second legend below it. Also, if you export to image, the custom HTML legend is lost since Plotly itself has no knowledge of it.

I'm currently hacking around this by using a horizontal annotation across the top of the plot for the symbols, but this is a poor solution because annotations can't scroll and trying to properly size and wrap this "pseudo-legend" annotation is difficult (near impossible to do reliably).

@nicolaskruchten
Copy link
Contributor

nicolaskruchten commented Mar 2, 2020

For a bit of context around how this might be implemented in the future... Right now we have legends (which can contain up to 1 item per trace, and where 1 trace can only be linked to 1 item) and colorbars for continuous color. One way forward would be to take every visual property that can be manipulated and add a colorbar-equivalent for it: size, symbol, line-dash, categorical-color etc. This is basically how ggplot and other grammar-of-graphics systems work.

Beyond this, there are other generalizations we could imagine that would involve multiple legends and a mapping from trace to legend, or the ability for 1 trace to be linked to multiple legend items or something like that.

In terms of roadmap, at the moment we aren't planning on working on this for the next few months, but if anyone here works for an organization that has a software budget, we do accept sponsorship for features, which would enable us to build these features faster :)

@nicolaskruchten
Copy link
Contributor

PS: I forgot to provide the link to follow in case anyone is interested in sponsoring this feature... it's https://plot.ly/products/consulting-and-oem/

@rben01
Copy link

rben01 commented Apr 18, 2020

Tacking on my +1 -- my use case is using px.line with c colors and d dash styles, I'd like a legend of length c+d instead of c*d (similar to seaborne's lineplot default legend).

image

@brian2222
Copy link

Referring to multiple legend for the case of multiple subplots...
Seems like there should be some outside the box thinking. This problem is already solved for colorbars. One can add as many as there are subplots and they magically show up.
It is also solved in some other way for axes, each subplot can have its own and then magically there is an xaxis1, xasis2...
Not sure how it works, but there must be a collection of these items, colorbars and axes, why not have a legend collection too, then simple assign it to the right one. I'd be happy to just number them like axes or have them magically appear like colorbars. But for goodness sake people do something!!!
If you pay for it I'll do it sure seems like a cop-out when its been needed for years.

@nicolaskruchten
Copy link
Contributor

Thank you for your enthusiasm @brian2222 :)

One problem with this approach is the problem we currently have with colorbars: there is no overlap-avoidance built-in. You can see this in action today when you have two colorbars, or one colorbar and one legend: they overlap. Implementing multiple legends “the easy way” would lead to them overlapping by default, which is pretty inelegant. Unfortunately, we don’t have the time or budget on our roadmap for the next few months to tackle the layout issue properly.

@brian2222
Copy link

brian2222 commented Jun 4, 2020

Thanks for your comment @nicolaskruchten. I appreciate your work and do love using plotly.
So I am confused. A colorbar has a location that it can be moved, I have to do this all the time and tweak them to work. Here is an example:

go.heatmap( ... colorbar=dict(len=0.27, y=.867), ...

I cannot move the legend around, but moving the colorbar works great, so I just have to limit my legend data and move the colorbar to achieve the layout I want. Are you saying if there was a second colorbar on the same subplot I couldn't do that?

Can you give me the 90 second overview of which files need to be modified and a general overview of the process that you believe needs to be followed to make this happen? I haven't contributed much to open source before but that is because I am just not comfortable with the process. If you pointed me in the right direct and I was able to understand the issue I might give it a go.

@nicolaskruchten
Copy link
Contributor

So actually you can move the legend around too, it has x/xref/xanchor attributes. What I was saying is that if you make a plot with both a legend and a colorbar, and you don't manually set their position, they will overlap by default, and this is a bit gross. If we "naively" implement multiple legends, then a plot with 2 legends will display with them overlapping unless you manually position them. It turns out that implementing an automatic overlap-avoidance system is really, really involved.

@nicolaskruchten
Copy link
Contributor

To expand a little: imagine you have a figure with 2 legends, each of which has two traces, each with a one-line, one-word name and the figure dimensions are 800px by 600px and your plot margins are 20px all around and your font is Open Sans size 14. You render the figure and the legends overlap, so you play a bit with the y value (in percentage units of the plotting area, not pixels!) of the second legend so they don't overlap any more.

Now if you change any of the above values (dimensions, number of traces, font sizes, number of lines of text per trace name) you have to play with legend2.y again to make sure there's no overlap.

This is the bit that's hard to write a robust algorithm for internally, and kind of unfortunate to force a user to do.

@GitHunter0
Copy link

Plotly amazingly covers almost all fundamental features expected from a plotting library, this is just one of the exceptions. Hope you guys can find an organization to finance this project.

@nicolaskruchten
Copy link
Contributor

So there are two totally distinct issues/requests here, which causes a bit of confusion, so I'm going to close this issue in favour of the following two:

1. Multiple legends: by size, symbol, color etc #5099 - this captures the original intent here of legends-by-visual-variable
2. Multiple legends: trace.legend and layout.legendN #5098 - this captures some of the other needs that have tagged along with the "multiple legends" title, basically of supporting something like legend-per-subplot

Neither of these items is on anyone's roadmap at the moment as far as I know although I would love for Plotly.js to support both! That said, we as maintainers would be happy to help someone from the community to implement it in Plotly.js, or to accept sponsorship to get it on to our short-term roadmap :)

@plotly plotly locked and limited conversation to collaborators Aug 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature something new
Projects
None yet
Development

No branches or pull requests