-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
RFC: Allow users to force zorder in 3D plots #14175
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
Comments
My view on this: Just try to implement this and see if it works. You can fork matplotlib, create a branch, change the code to your liking. Then, you see if it works for your application or not. Creating a PR from that branch is then trivial. So just create the PR. At this point everyone can look at the actual implementation and identify potential flaws; also you get feedback from the online test system. Even if this does not make it into matplotlib, you have gained the following:
And not to forget, if it does work and make it into the library, you have helped the worldwide community to get a better matplotlib. |
It's already working locally for my own purposes, but to my mind a pull request implies I think I've done the full job. If it's acceptable to submit a work-in-progress in order to receive feedback, then sure, I don't mind doing that. Either way, thanks for the response! |
It’s often useful to come up with an example, show the with-patch change and compare to the example run on master so we can see the difference Otherwise you are asking us to apply your patch and come up w our own example. |
That’s helpful as well but I meant what code did you test with and what did the plots look like before and after? Include the plots here. |
I might spend the time on that later, but I don't think it should be necessary to get feedback about the idea. |
I am not really all that convinced that this option would be all that beneficial. For example, when interacting with the scene, particularly with rotating it, the user would need to recalculate the zorder themselves or it will look all wrong. Now, perhaps if we frame this feature in the right way, such as "don't let matplotlib get in my way, I'll take full responsibility for zsorting", then maybe this feature would make sense? |
Github specifically has a draft pr feature that's absolutely welcome here. Do you think something could be added to the docs/README to make it clearer that matplotlib accepts those sorts of PRs? |
@WeatherGod @story645 Thanks, that's helpful! |
Been thinking on this over the weekend. The more I think about it, the less I like the idea of a flag to turn on and off the depth-calculation. What if we look at this differently, and allow users to plug in a different function for calculating the z value, and let the default function be the current one? In some respects, we actually do this right now by providing a choice between 2 different 3d projections. |
As it stands, the projections just return a value that gets sorted and is used to set zorder. So the zorder is already the ultimate arbiter, but it gets overwritten during the draw. That already seems a bit wonky to me, so I don't know why you'd then add a layer that would force a user to provide a function that has to handle the depth calculation for two different object types (collections and patches), which ultimately is just going to set the zorder anyway. They already have access to the zorder of the objects. It's already a bit odd that the zorder they set gets completely ignored. They can already write their own functions to determine and set the zorder of those objects. I'd think they could also use the existing projection functions, else we could expose them. That all said, there's apparently stuff going on inside those projection functions that do more than just determine the order, so as it stands they need to be called anyway. So the flag wouldn't stop them from running, it'd just ignore their return values. I've also learned that the draw function gets called more than once for a single plot, so I'm hoping we can just ignore the offset too. |
As a user, I would like to say that a mechanism of this kind would indeed be very useful. I got into the issue several times while producing static figures for articles. For this use case playing nice with interactivity is not required. But being able to override the default behavior and to force the z-order is extremely useful. As evidenced by the current pull request and the linked bugs and SO questions in #14175 (comment) (also issue #14148), this is a common issue. The current PR gives me hope that it will soon be possible to manually set the z-order of elements in a 3D plot in an easy way! I really hope it does not end up abandoned like #12744! |
Merged |
How does one use this feature? Is it documented anywhere? I have some old code that does some zorder tricks but it's inexplicably broken now, so I'm hoping enabling this will fix it again. |
Oh never mind, it's not the z axis stuff that's broken, it's something else. Still sounds like it would be helpful to document this though. |
It's a parameter to the Axes. https://matplotlib.org/3.5.0/api/_as_gen/mpl_toolkits.mplot3d.axes3d.Axes3D.html?highlight=computed_zorder |
At present, the draw order order in 3D plots is determined exclusively by sorting the values returned by calling do_3d_projection() in each collection/patch:
matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py
Lines 294 to 307 in 40583b0
However, this sorting is not always ideal and a common issue reported by users. I'd propose adding a "force_zorder" optional parameter to Axes3D (defaulting to False) that would ignore the above calculation and instead use the zorder already stored in each collection/patch, i.e.
This keeps existing behavior as default, but allows users to override that behavior. This does allow users to specify duplicate or negative zorders, as they can in 2D plots, but that hasn't generated errors in my testing.
However, not being at all familiar with the deeper workings, I'd rather get comments/concerns from the matplotlib maintainers and contributors before setting off to produce a full pull request.
Thanks!
The text was updated successfully, but these errors were encountered: