You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, there is no way to set an absolute draw order for traces. It would be very useful to have a property to determine the global draw order, e.g. to give a trace the value of 1 to make sure it is always drawn on top of all other traces and another trace the value of 9999 to make sure it is drawn behind all other traces.
Let me break down the current behavior a little:
(0) in SVG, there's no concept like z-index in HTML; items later in the DOM are always on top of items earlier in the DOM.
(1) if you have multiple sets of x or y axes overlaying each other, all the traces on the same axes are grouped together and either in front or behind other axes. I would need to verify the details, but I believe higher-index x axes are in front, and for the same x axis higher-index y axes are in front, ie x2y2>x2y>xy2>xy.
(2) Traces of different type have a fixed order, as we put them all in different "layer" groups:
Meaning scatter traces are always on top, image traces are always on bottom, everything in between is as in this list.
(3) After that, traces of the same type are ordered by their index in data.
So with all of that in mind, which of these three categories describes your use cases?
It would be fairly easy to add an attribute to change (3) - the ordering of traces of the same type on the same axes, but hard to add a way to change the other orderings (different types, or on different axes).
But there's a workaround: make extra axes - that can be set to be overlaying and matching the main axes and with all their marks disabled, so really their only effect is to change the layering - and put the traces intended to be in back on lower-numbered axes, traces in front on higher-numbered axes.
The scenario we encountered is in the area of (1). We have scatter traces linked to yaxis2 and bar traces linked to yaxis1. The scatter traces should be drawn on top of the bar traces. From your explanation, the best solution would be to add additional axes with higher indexes (e.g. yaxis3) and re-assign the bar traces to these.
We simplified the axis logic for our less technical end users as follows:
There are only two y-axes, one left and one right.
There are only two x-axes, one top and one bottom.
There is a rank parameter on each trace object, which specifies the global drawing order for the traces.
We could build a workaround on our side that would be invisible to the user by automatically creating multiple axes based on the rank parameter under the hood. However, I feel like such a property could be useful to the plotly community at large and it would probably be easier for you guys to implement than for us.
To summarize:
It would be great, if the rank property on the traces would cover (1), (2) and (3) of your list above.
Summing up past discussions of solution design for this one.
API
Add zindex property to cartesian traces, which accepts an integer
Traces of higher zindex are drawn on top of traces of lower zindex (consistent with CSS convention)
Questions
Property name and stacking direction -- i.e. are lower or higher numbers drawn on top? I like following an existing convention for simplicity but open to other conventions
Applies to all cartesian traces, or do any need to be excluded?
Changes to trace drawing logic -- largely within src/plots/cartesian/index.js
Separate traces into overlapping sets, i.e. traces that don't overlap each other should be in different sets (different subplots, basically)
Figure out stacking order implied by zindex
Figure out how many different stacked containers are needed to make the default trace stacking order match the order specified by zindex (Currently, just one container per axis pair is used)
Create containers and draw traces in their correct containers
Make sure all containers are transformed during zoom/pan rather than just one per axis pair
Activity
gvwilson commentedon Jul 17, 2024
Let me break down the current behavior a little:
(0) in SVG, there's no concept like
z-indexin HTML; items later in the DOM are always on top of items earlier in the DOM.(1) if you have multiple sets of x or y axes overlaying each other, all the traces on the same axes are grouped together and either in front or behind other axes. I would need to verify the details, but I believe higher-index x axes are in front, and for the same x axis higher-index y axes are in front, ie x2y2>x2y>xy2>xy.
(2) Traces of different type have a fixed order, as we put them all in different "layer" groups:
Meaning scatter traces are always on top, image traces are always on bottom, everything in between is as in this list.
(3) After that, traces of the same type are ordered by their index in
data.So with all of that in mind, which of these three categories describes your use cases?
It would be fairly easy to add an attribute to change (3) - the ordering of traces of the same type on the same axes, but hard to add a way to change the other orderings (different types, or on different axes).
But there's a workaround: make extra axes - that can be set to be overlaying and matching the main axes and with all their marks disabled, so really their only effect is to change the layering - and put the traces intended to be in back on lower-numbered axes, traces in front on higher-numbered axes.
gvwilson commentedon Jul 17, 2024
The scenario we encountered is in the area of (1). We have scatter traces linked to yaxis2 and bar traces linked to yaxis1. The scatter traces should be drawn on top of the bar traces. From your explanation, the best solution would be to add additional axes with higher indexes (e.g. yaxis3) and re-assign the bar traces to these.
We simplified the axis logic for our less technical end users as follows:
rankparameter on each trace object, which specifies the global drawing order for the traces.We could build a workaround on our side that would be invisible to the user by automatically creating multiple axes based on the
rankparameter under the hood. However, I feel like such a property could be useful to the plotly community at large and it would probably be easier for you guys to implement than for us.To summarize:
It would be great, if the
rankproperty on the traces would cover (1), (2) and (3) of your list above.gvwilson commentedon Jul 17, 2024
Summing up past discussions of solution design for this one.
API
zindexproperty to cartesian traces, which accepts an integerzindexare drawn on top of traces of lowerzindex(consistent with CSS convention)Implementation (based on notes from @alexcjohnson)
src/plots/cartesian/index.jszindexzindex(Currently, just one container per axis pair is used)gvwilson commentedon Jul 17, 2024
See great progress: plotly/plotly.js#6918
archmoj commentedon Jul 24, 2024
We could possibly close this one as
zorderis implemented. No?gvwilson commentedon Jul 24, 2024
agreed