Skip to content

MNT: Remove auto-flattening of input data to pcolormesh #24638

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

Merged
merged 1 commit into from
Jan 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6220,9 +6220,6 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
X, Y, C, shading = self._pcolorargs('pcolormesh', *args,
shading=shading, kwargs=kwargs)
coords = np.stack([X, Y], axis=-1)
# convert to one dimensional array, except for 3D RGB(A) arrays
if C.ndim != 3:
C = C.ravel()

kwargs.setdefault('snap', mpl.rcParams['pcolormesh.snap'])

Expand Down
32 changes: 16 additions & 16 deletions lib/matplotlib/tests/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -914,13 +914,13 @@ def test_quadmesh_vmin_vmax():
norm = mpl.colors.Normalize(vmin=0, vmax=1)
coll = ax.pcolormesh([[1]], cmap=cmap, norm=norm)
fig.canvas.draw()
assert np.array_equal(coll.get_facecolors()[0, :], cmap(norm(1)))
assert np.array_equal(coll.get_facecolors()[0, 0, :], cmap(norm(1)))

# Change the vmin/vmax of the norm so that the color is from
# the bottom of the colormap now
norm.vmin, norm.vmax = 1, 2
fig.canvas.draw()
assert np.array_equal(coll.get_facecolors()[0, :], cmap(norm(1)))
assert np.array_equal(coll.get_facecolors()[0, 0, :], cmap(norm(1)))


def test_quadmesh_alpha_array():
Expand All @@ -935,16 +935,16 @@ def test_quadmesh_alpha_array():
coll2 = ax1.pcolormesh(x, y, z)
coll2.set_alpha(alpha)
plt.draw()
assert_array_equal(coll1.get_facecolors()[:, -1], alpha_flat)
assert_array_equal(coll2.get_facecolors()[:, -1], alpha_flat)
assert_array_equal(coll1.get_facecolors()[..., -1], alpha)
assert_array_equal(coll2.get_facecolors()[..., -1], alpha)
# Or provide 1-D alpha:
fig, (ax0, ax1) = plt.subplots(2)
coll1 = ax0.pcolormesh(x, y, z, alpha=alpha_flat)
coll1 = ax0.pcolormesh(x, y, z, alpha=alpha)
coll2 = ax1.pcolormesh(x, y, z)
coll2.set_alpha(alpha_flat)
coll2.set_alpha(alpha)
plt.draw()
assert_array_equal(coll1.get_facecolors()[:, -1], alpha_flat)
assert_array_equal(coll2.get_facecolors()[:, -1], alpha_flat)
assert_array_equal(coll1.get_facecolors()[..., -1], alpha)
assert_array_equal(coll2.get_facecolors()[..., -1], alpha)


def test_alpha_validation():
Expand Down Expand Up @@ -992,7 +992,7 @@ def test_color_logic(pcfunc):
pc.update_scalarmappable() # This is called in draw().
# Define 2 reference "colors" here for multiple use.
face_default = mcolors.to_rgba_array(pc._get_default_facecolor())
mapped = pc.get_cmap()(pc.norm(z.ravel()))
mapped = pc.get_cmap()(pc.norm(z.ravel() if pcfunc == plt.pcolor else z))
# GitHub issue #1302:
assert mcolors.same_color(pc.get_edgecolor(), 'red')
# Check setting attributes after initialization:
Expand All @@ -1011,30 +1011,30 @@ def test_color_logic(pcfunc):
# Reset edgecolor to default.
pc.set_edgecolor(None)
pc.update_scalarmappable()
assert mcolors.same_color(pc.get_edgecolor(), mapped)
assert np.array_equal(pc.get_edgecolor(), mapped)
pc.set_facecolor(None) # restore default for facecolor
pc.update_scalarmappable()
assert mcolors.same_color(pc.get_facecolor(), mapped)
assert np.array_equal(pc.get_facecolor(), mapped)
assert mcolors.same_color(pc.get_edgecolor(), 'none')
# Turn off colormapping entirely:
pc.set_array(None)
pc.update_scalarmappable()
assert mcolors.same_color(pc.get_edgecolor(), 'none')
assert mcolors.same_color(pc.get_facecolor(), face_default) # not mapped
# Turn it back on by restoring the array (must be 1D!):
pc.set_array(z.ravel())
pc.set_array(z.ravel() if pcfunc == plt.pcolor else z)
Comment on lines 1024 to +1025
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Both of these situations feel undesirable...

  • The must be 1D! is the way it currently is and doesn't feel right after we've initialized our array with the 2D version pcolor(z).
  • It also doesn't feel great to change this and have to do the if pcfunc ... and change between 1D and 2D depending on which pcolor incantation I chose.

Copy link
Member

Choose a reason for hiding this comment

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

The flattening in pcolormesh is a historical artifact; I think the move to accept it as fundamentally 2-D is good.
Pcolor is rarely a better choice than pcolormesh. When it is, it is likely because it can generate a set of
colored quadrilaterals that don't have to fill out a 2-D domain. I think we should embrace this difference between
pcolormesh and pcolor, so I don't have a problem with your special-casing in the test. I'm open to discussing
ideas for backwards-compatible improvements to pcolor, so that it could also take a 2-D array in set_array,
but it doesn't seem like a priority.

pc.update_scalarmappable()
assert mcolors.same_color(pc.get_facecolor(), mapped)
assert np.array_equal(pc.get_facecolor(), mapped)
assert mcolors.same_color(pc.get_edgecolor(), 'none')
# Give color via tuple rather than string.
pc = pcfunc(z, edgecolors=(1, 0, 0), facecolors=(0, 1, 0))
pc.update_scalarmappable()
assert mcolors.same_color(pc.get_facecolor(), mapped)
assert np.array_equal(pc.get_facecolor(), mapped)
assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 1]])
# Provide an RGB array; mapping overrides it.
pc = pcfunc(z, edgecolors=(1, 0, 0), facecolors=np.ones((12, 3)))
pc.update_scalarmappable()
assert mcolors.same_color(pc.get_facecolor(), mapped)
assert np.array_equal(pc.get_facecolor(), mapped)
assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 1]])
# Turn off the mapping.
pc.set_array(None)
Expand All @@ -1044,7 +1044,7 @@ def test_color_logic(pcfunc):
# And an RGBA array.
pc = pcfunc(z, edgecolors=(1, 0, 0), facecolors=np.ones((12, 4)))
pc.update_scalarmappable()
assert mcolors.same_color(pc.get_facecolor(), mapped)
assert np.array_equal(pc.get_facecolor(), mapped)
assert mcolors.same_color(pc.get_edgecolor(), [[1, 0, 0, 1]])
# Turn off the mapping.
pc.set_array(None)
Expand Down