-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Update art3d.py to address strange behavior of depthshading on 3D scatterplots with close points #23085
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
Conversation
This update changes the depthscale behavior from the original Normalize method to an improved version that behaves well even when points are closely spaced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for opening your first PR into Matplotlib!
If you have not heard from us in a while, please feel free to ping @matplotlib/developers
or anyone who has commented on the PR. Most of our reviewers are volunteers and sometimes things fall through the cracks.
You can also join us on gitter for real-time discussion.
For details on testing, writing docs, and our review process, please see the developer guide
We strive to be a welcoming and open project. Please follow our Code of Conduct.
Fixed line lengths, added handling of zero-length datasets when computing the data scale.
Added a small value to the denominator of the "sats" calculation to avoid division by zero error when plot is empty (scale is zero). Removed trailing whitespace.
I think I've addressed the other issues, but am still getting image comparison failures. Is this to be expected when making changes related to how plots are displayed? |
Yes, it is expected. The RMS numbers are quite small, so only a number of pixels. I will let someone else have a proper say on this, but I believe that we should provide a fallback method for persons relying on the previous appearance. Unless it is obvious that the previous was always incorrect. |
If you please can provide the resulting figures from e.g. #22861 after applying the changes here, it would simplify the review. |
Renamed get_data_scale and dscl to indicate that they are private, added description of function's purpose, and replaced np.power with np.sqrt.
Forgot this portion of the update earlier. Fixes the alpha draw order flipping as the point depth inverts even though the alpha should not change per point.
Missed the update to _dscl after re-adding code. Updated now.
I've attached some screenshots below showing the updated behavior. This is with no alpha input, with depth-shading on. You can see how the alpha becomes uniform when depth is uniform (1st image), then fades proportionally to draw depth, including when draw depth reverses (2nd vs 3rd image): When there is an alpha input (with depthshading on or off), the result is that the slight rotation of the plot no longer results in a sudden flip of alpha values as the depth order reverses: Note that this behavior is only implemented for Path3DCollection since the bug is related to 3D scatterplots, but may be applicable to other collections if needed. |
I feel like I should explain the comment "# Solid near, transparent far, solid default" further: depending on the equation used for calculating "sats" you can change the behavior of the depth-shading. The meaning is as follows: I felt that the other three versions were further from the desireable/existing depth-shading behavior, but could be interesting to include as alternative modes. Please let me know if you think "mode selection" is a worthwhile inclusion. Mode selection could also allow the old depth-shading behavior to be selected if desired. |
Only one dataset of (X, Y, Z) needs to be checked for zero length assuming all have the same length. Instead of using a small constant in the denominator it's cleaner to just check for '_dscl==0' and return ones instead. This applies for datasets with no datapoints, all the same datapoint such that no scale can be estimated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find some of the comments redundant (as noted); they should describe why, not what.
Fixed some word wrapping, made get_data_scale more compact, replaced _dscl with the more descriptive _data_scale, removed redundant comments, added clearer comments for implementation of shading modes
Thanks for this. This behavior was driving me crazy. |
This is cool work! A couple of requests:
I have pushed this to the 3.8 milestone. |
Definitely, though I'm not sure what appropriate string representations would be. My previous convention was to summarize behavior as follows:
Are there guidelines for these/examples I could reference? Thanks for the suggestions. |
Hi @Obliman - For the tests, you can take a look at this file which contains the tests for |
Thanks for the reminder, I've made some updates. I've thought about the changes I had proposed and the whole "different modes" thing was just unnecessarily complicated/probably not that useful. I've since simplified it to be three kwargs:
I've added the "what's new" document and updated other classes to provide access to the user when creating scatter plots or otherwise interacting with Patch3DCollection/Path3DCollection objects. Edit: one thing I'm still unsure about is whether there are any tests that need to be set up for this. Can anyone provide guidance, please? |
Yes, I think that there should be some tests for this to make sure that possible later changes does not break the behavior. One suggestion is to add an image comparison test with a number of subplots, each subplot illustrating some combination of the new behavior. Looking at the code coverage, I can imagine a 2 x 2 subplot where each combination of legacy/new and inverted/non-inverted is plotted. (Right now, only new and non-inverted seems to be tested.) For min-alpha one can consider something similar or simply checking the alphas in the resulting collection to confirm that they are as expected (if one can avoid image tests that is slightly better since storing images leads to a rather large repo...). |
Oh, and for "completeness", one can also call the new |
This is breaking tests that were expecting the old behavior. We either need to manually set the legacy behavior in the tests and add an API change note or we need to set the default to set the default value of Rather than adding a bunch of parameters named Moving this to 3.10 and should talk about this on the call as soon as 3.9 is branched. |
Hi @nhansendev, are you still interested in finishing up this PR? |
Hey, sorry for the delay in response. If someone else wants to tackle the last steps I would appreciate it. |
Sounds good @nhansendev, thank you for the work getting it to this point! I'll finish up the remaining items in #29287 |
Commenting on this PR to notify original authors - what is the use case behind the My personal leaning here is to consider the current / |
This was trivial to implement, so was added in case someone finds it useful. If it's just adding more work then I think it can be removed.
I agree that the legacy behavior represents an undesirable visual bug. Keeping backwards compatibility was suggested earlier, but it's probably not going to significantly affect generated plots given it was barely failing the old image tests. |
Fix is merged in, thank you again for the initial work on this! |
Thank you for finishing it 🥇 |
PR Summary
This update changes the depthshade behavior from the original normalization method to an improved version that behaves well even when points are closely spaced. This addresses issue 22861
I'm not clear on how to run the appropriate pytest unit tests for this file (if any), so I would appreciate some guidance there.
PR Checklist
Tests and Styling
pytest
passes).flake8-docstrings
and runflake8 --docstring-convention=all
).Documentation
doc/users/next_whats_new/
(follow instructions in README.rst there).doc/api/next_api_changes/
(follow instructions in README.rst there).