Hello everyone!
I'd wish for the legend to have xshift and yshift attributes, so I could position it more easily where I want it to be.
Currently I solved most of my positioning problems by using xshift/yshift with annotations and shapes but for some elements (for example "hacked" x axis titles via annotations) that are above where I want the legend to be I have huge problems of positioning for responsive layouts. (Especially with differing heights of the plot div when altering it for narrow displays.)
I can't tell how much work it would mean to implement this for the legend, but since other objects do have these attributes I hope it wouldn't create too much work. It would have an immense impact on how I could layout responsively, though, and would fix a myriad of problems that I have with layouting.
Makes sense, probably a fairly easy add. Feel like making a PR?? ๐
@alexcjohnson If cargo-culting away at the commit which added annotation xshift/yshift will do, I might take a shot in about 3-4 weeks. But I bet my code wouldn't be up to snuff regarding best practices :D
So legend.xshift and legend.yshift would be in pixels?
@etpinard correct
@alexcjohnson Would I have to create tests as well?
Would I have to create tests as well?
Someone would ๐ Most likely just an image test or two would suffice, and we can help, particularly if you can provide a figure JSON ({data, layout}) that shows the use of these shifts to suit your own use case.
As we're at it anyway: Would it be too hard to also include something like legend.rows where you can force the legend to distribute given legend items on so many rows?
Use-case: You set filtered legends invisible when downloading the PNG and if you have a lot of legend items in orientation = 'h' they will break into several rows. Now if you filter enough legend items it will reduce to one row but keep the positioning and thus a margin is created that messes up your layout because you don't want such a big margin to the following annotation elements.
An alternative way would be to somehow access something like legend.height that is a read-only attribute which you can access while layouting (is there something like a layout-hook?) or after layouting and relayout the positioning of everything that relies on the height/margin of the legend.
If you can force a number of rows you can emulate the legend height by knowing the font size and finding a magic number that you can multiply with legend rows combined with the legend margin itself.
EDIT: I currently have a legend with an approximate height of 160px due to a lot of <br> and a lot of legend items and not a huge amount of width. Filtering out enough traces, so that only one row of legend items remains, creates a huge margin ๐. Knowing the legend height on draw would relieve me of this problem ๐ฟ.
So basically I found a workaround for my use-case by checking out fullDataLayout on a new plot. I created an invisible plot off the visible area and draw my stuff on there; I take the legend._height and only then draw the image that shall be downloaded.
I'm not in need of this feature anymore, so you may close it if you want or keep it for someone to work on ๐ธ.
EDIT: Being able to predict the top margin of the legend (EDIT2: By positioning through yshift instead of adjusting the legend.y) is still somewhat desirable... Also drawing a plot just for the sake of getting the legend height is really demanding for the client. Will try to take a shot at xshift/yshift for legend in a few weeks; maybe one of you guys has an idea for an efficient way of calculating the legend height?
@alexcjohnson Any hints on how we could expose a Plotly function that calculates a legend height for a given plot width and data? Could you pinpoint me to the exact scope of code that calculates the legend dimensions? ๐ฟ
I think this would also address #1594, at least partially. It'll still probably require manually increasing the margin and then applying the shift to the legend, but at least it would provide some options for dealing with legend/axis overlaps.
Just a quick question/addition: Is it possible to xshift/yshift shapes? And if not: could we also add this? ๐น
EDIT: To give a use-case: I want to display a horizontal line (shape line with width: 1 and y0=y1 and x0: 0 and x1: 0.9 with xref: "paper") and have an annotation at the end of it (x: 0.9 y: y0 and align: "left"). With fixed plot sizes that's not a problem but when you are able to achieve responsiveness you have vastly different results when using paper as ref due to variable plot width.
If I could use xshift, I could just offset the line shape by the same amount of pixels that I'd offset the annotation from the right end of the plot (shape x1: 1 with xshift: -20 and same with the annotation).
I guess I'll have to try and use x as xref instead now :D.
EDIT2: Actually xref: "x" doesn't help... the bars in my plot have varying width to which the annotation text size isn't adapting resulting in almost the same problem ๐น
Hello everyone, is there any progress on this? ๐ธ
I don't know if it was a shift in versions but legend._height returns wrong heights for me in some cases which results in broken code functionality for me now ๐ข . It basically says that the legend has less height than is actually displayed.
This seems to be another problem with usage of <br> tags as far as I can tell. If I remove all <br> tags from trace names I can't reproduce it anymore.
EDIT: Nevermind, I had a bug in my margin calculation. Fixed it ^^.
This issue has been tagged with NEEDS SPON$OR
A community PR for this feature would certainly be welcome, but our experience is deeper features like this are difficult to complete without the Plotly maintainers leading the effort.
Sponsorship range: $5k-$10k
What Sponsorship includes:
Please include the link to this issue when contacting us to discuss.