plotly / plotly.js

Open-source JavaScript charting library behind Plotly and Dash
https://plotly.com/javascript/
MIT License
16.92k stars 1.85k forks source link

Shapes that reference multiple axes simultaneously #7151

Open alexcjohnson opened 2 weeks ago

alexcjohnson commented 2 weeks ago

The x or y coordinates in shapes currently reference exactly one axis each, but if we could allow multiple axis references within one shape, you could link up features in different subplots in a way that reacts as each subplot is independently zoomed or panned.

This was mentioned a long time ago on the forum: https://community.plotly.com/t/draw-a-line-between-data-points-of-different-subplots/29115 (with a partial workaround suggested by @empet)

Screenshot 2024-09-11 at 10 10 21

and various times on SO, eg https://stackoverflow.com/questions/44670708/draw-line-on-top-of-subplot-to-render-a-zoom-effect

Screenshot 2024-09-11 at 10 11 19

and https://stackoverflow.com/questions/17543359/drawing-lines-between-two-plots-in-matplotlib

Screenshot 2024-09-11 at 10 09 28

My interest in this stems from striplogs, a common tool in mining and oil & gas for analyzing drilling data, where you want to correlate features you see in multiple drillholes, for example https://help.rockware.com/rockworks17/WebHelp/striplog_h2h.htm where you can see lines or filled regions that are paper-referenced in their x coordinates, but their y coordinates reference a different axis for each drill hole:

Screenshot 2024-09-11 at 10 07 23

and it could be particularly powerful to pan each drillhole axis separately to align one of these features and see how the other features do or don't line up.


As to API: for simple shapes (lines are the most important one here) this could be accomplished by extending the idea of xref to add x0ref and x1ref (similarly for y). For path shapes (important for the filled areas in the striplog use case) this would need to be handled within the path string, perhaps something like :x3 after a coordinate to describe its reference, so the paths would look like: "M0:paper 470:y H0.2:paper L0.3:paper 392:y2 H0.5:paper L0.7:paper 524:y3 H0.9:paper". Then we could either ignore xref/yref, require you to set something like xref='variable' to opt in to this behavior, or allow an xref and use that for any coordinate for which you omit the reference.

Then when drawing, the pixel coordinates would need to be re-evaluated every time any of the referenced axes was zoomed or panned - which I think we may do today anyway, unlike graph data that just has a svg transform applied to it during a zoom or pan and is only re-evaluated when the interaction is done.