Plotly.js: Support for multiple legends

Created on 10 May 2017  ·  36Comments  ·  Source: plotly/plotly.js

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

feature

Most helpful comment

Looking forward to have this feature available.

All 36 comments

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.

Are there any concrete plans to support multiple legends in the near future?

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).

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.

Hopefully, this could be done also in javascript plotly!!

Has there been any progress on this?

Looking forward to have this feature available.

Is there any update on this?

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

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.

Is there any update on this? I would really like to know how to attach a legend on the right hand side of each subplot.

I was excited to see that this issue had been raised two years ago, hoping that it would be solved. Has there been any progress?

Going to add another bump to this. I'm particularly interested in the interaction with ggplotly, since currently the lack of support for multiple legends changes the plot in unexpected ways.

@alexcjohnson Can you shed a light on if giving legend groups an annotation/title is possible by now? So it basically would look like the mockup above where the legend groups have text above them.

Indeed, it would be great to have multiple legends available ! It would also solve this issue with ggplotly #1164

Is there any update. Thank you

This would be really handy. Is there an update?

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

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

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

https://github.com/ropensci/plotly/issues/1164#issuecomment-489665978

@jessicajturner this might be of interest to you too.

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.

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

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

Tacking on interest in this!

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

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).

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 :)

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/

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

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.

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.

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.

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.

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.

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.

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

  1. 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 :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

etpinard picture etpinard  ·  3Comments

HunterMcGushion picture HunterMcGushion  ·  3Comments

emanuelsetitinger picture emanuelsetitinger  ·  3Comments

WG- picture WG-  ·  3Comments

n-riesco picture n-riesco  ·  3Comments