Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[BUG] Fix alpha bug on 3D PathCollection plots. #25478

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

ricmperes
Copy link

PR Summary

Quick fix of bug on treatment of alpha parameter on the mplot3d toolkit, reported in issue #25446, following @oscargus and @tacaswell directions on the issue thread.

For Patches, no changed seemed to be needed. Might need further testing since it's the same piece of code repeated:

def _maybe_depth_shade_and_sort_colors(self, color_array):
color_array = (
_zalpha(color_array, self._vzs)
if self._vzs is not None and self._depthshade
else color_array
)
if len(color_array) > 1:
color_array = color_array[self._z_markers_idx]
return mcolors.to_rgba_array(color_array, self._alpha)

A script to test the fix can be found in this gist: https://gist.github.com/ricmperes/a69d876d2cf7333ae9cf713ecb25b474

Result after fix:
alpha_issue_test

PR Checklist

Documentation and Tests

  • Has pytest style unit tests (and pytest passes)
  • Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • New plotting related features are documented with examples.

Release Notes

  • New features are marked with a .. versionadded:: directive in the docstring and documented in doc/users/next_whats_new/
  • API changes are marked with a .. versionchanged:: directive in the docstring and documented in doc/api/next_api_changes/
  • Release notes conform with instructions in next_whats_new/README.rst or next_api_changes/README.rst

Copy link

@github-actions github-actions bot left a 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.

@oscargus
Copy link
Member

Thanks! Can you please add a test for this as well?

I think that plotting something like in the original issue and then checking that the alpha-value of the "correct" position(s) (row 10000 to 19999) of scat3d.get_facecolor() is 0 would do. (No need for image tests.)

@ksunden
Copy link
Member

ksunden commented Mar 16, 2023

Test failure is related:

test_scatter3d_sorting png-True -expected

test_scatter3d_sorting png-True

The test:

@pytest.mark.parametrize('depthshade', [True, False])
@check_figures_equal(extensions=['png'])
def test_scatter3d_sorting(fig_ref, fig_test, depthshade):
"""Test that marker properties are correctly sorted."""
y, x = np.mgrid[:10, :10]
z = np.arange(x.size).reshape(x.shape)
sizes = np.full(z.shape, 25)
sizes[0::2, 0::2] = 100
sizes[1::2, 1::2] = 100
facecolors = np.full(z.shape, 'C0')
facecolors[:5, :5] = 'C1'
facecolors[6:, :4] = 'C2'
facecolors[6:, 6:] = 'C3'
edgecolors = np.full(z.shape, 'C4')
edgecolors[1:5, 1:5] = 'C5'
edgecolors[5:9, 1:5] = 'C6'
edgecolors[5:9, 5:9] = 'C7'
linewidths = np.full(z.shape, 2)
linewidths[0::2, 0::2] = 5
linewidths[1::2, 1::2] = 5
x, y, z, sizes, facecolors, edgecolors, linewidths = [
a.flatten()
for a in [x, y, z, sizes, facecolors, edgecolors, linewidths]
]
ax_ref = fig_ref.add_subplot(projection='3d')
sets = (np.unique(a) for a in [sizes, facecolors, edgecolors, linewidths])
for s, fc, ec, lw in itertools.product(*sets):
subset = (
(sizes != s) |
(facecolors != fc) |
(edgecolors != ec) |
(linewidths != lw)
)
subset = np.ma.masked_array(z, subset, dtype=float)
# When depth shading is disabled, the colors are passed through as
# single-item lists; this triggers single path optimization. The
# following reshaping is a hack to disable that, since the optimization
# would not occur for the full scatter which has multiple colors.
fc = np.repeat(fc, sum(~subset.mask))
ax_ref.scatter(x, y, subset, s=s, fc=fc, ec=ec, lw=lw, alpha=1,
depthshade=depthshade)
ax_test = fig_test.add_subplot(projection='3d')
ax_test.scatter(x, y, z, s=sizes, fc=facecolors, ec=edgecolors,
lw=linewidths, alpha=1, depthshade=depthshade)

Looks like an interaction with depthshade = True. In this case it's a "compare equal" not a "compare to static reference" test, so pretty clear that the two methods of plotting should result in the same image (plotting in subsets of markers with the same properties vs plotting in one call).

return mcolors.to_rgba_array(color_array, self._alpha)

if self._alpha is not None:
converted_alphas = color_array[:, 3] * self._alpha
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure this will never get an RGB (vs RGBA) array?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @tacaswell. Good point, if depthshape is specified as False a RGBA type array might get passed. I put an escape clause for this case.

Suggested change
converted_alphas = color_array[:, 3] * self._alpha
return mcolors.to_rgba_array(color_array, self._alpha)

@scottshambaugh scottshambaugh added the PR: bugfix Pull requests that fix identified bugs label Mar 17, 2023
@ricmperes
Copy link
Author

Debugging why the test_scatter3d_sorting is failing I ran it with a clean version of matplotlib and the output seems to have no depth-related shading, likely because alpha=1 is parsed. To be sure, when depthshade=True this is not the intended behaviour, right?
Output bellow:
test_scatter3d_sorting png-True -expected

@scottshambaugh
Copy link
Contributor

Since depthshade=True is the default, I would expect that manually setting the alpha parameter would override the depth shading, but I don't actually know what the intent here is. @ricmperes I know this PR has been hanging for a bit - are you still interested in working on it?

@scottshambaugh
Copy link
Contributor

Hi @ricmperes, a fix to scatter plot depth shading was just merged in here: #29287

I think that should resolve the test failure you were seeing. Are you still interested in working on this PR?

@ricmperes
Copy link
Author

Perfect, that's great! I can rebase, test and if fixed, then close the PR. Thanks!

@scottshambaugh
Copy link
Contributor

Hi @ricmperes, are you still interested in working on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: bugfix Pull requests that fix identified bugs status: needs rebase topic: mplot3d
Projects
Status: Needs decision
Development

Successfully merging this pull request may close these issues.

[Bug]: Nan values in scatter 3d plot show in black colour when alpha parameter is passed.
6 participants