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

Skip to content

Commit 504ed6f

Browse files
committed
Incorporating feedback from @story645
1 parent ce1dcfd commit 504ed6f

7 files changed

Lines changed: 61 additions & 77 deletions

File tree

lib/matplotlib/axes/_axes.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5725,12 +5725,12 @@ def imshow(self, X, cmap=None, norm=None, *, aspect=None,
57255725
colors using normalization and a colormap. See parameters *norm*,
57265726
*cmap*, *vmin*, *vmax*.
57275727
- (K, M, N): multiple images with scalar data. Must be used
5728-
with a multivariate or bivariate colormap. See *cmap*.
5728+
with a multivariate or bivariate colormap that supports K channels.
57295729
- (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
57305730
- (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
57315731
i.e. including transparency.
57325732
5733-
Here M and N define the rows and columns of the image.
5733+
The dimensions M and N are the number of rows and columns of the image.
57345734
57355735
Out-of-range RGB(A) values are clipped.
57365736
@@ -6218,12 +6218,17 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
62186218
# we need to get the colorizer object to know the number of
62196219
# n_variates that should exist in the array, we therefore get the
62206220
# colorizer here.
6221-
colorizer = mcolorizer.ColorizingArtist._get_colorizer(norm=norm,
6222-
cmap=cmap,
6223-
colorizer=colorizer)
6224-
if colorizer.norm.n_input > 1:
6225-
data = mcolorizer._ensure_multivariate_data(colorizer.norm.n_input, args[0])
6226-
args = (data, *args[1:])
6221+
colorizer_obj = mcolorizer.ColorizingArtist._get_colorizer(norm=norm,
6222+
cmap=cmap,
6223+
colorizer=colorizer)
6224+
if colorizer_obj.norm.n_input > 1:
6225+
# Valid call signatures for pcolor are with args = (C) or args = (X, Y, C)
6226+
# If provided, _pcolorargs will check that X, Y and C have the same shape.
6227+
# Before this check, we need to convert C from shape (K, N, M), where K is
6228+
# the number of variates, to (N, M) with a data type with K fields.
6229+
data = mcolorizer._ensure_multivariate_data(colorizer_obj.norm.n_input,
6230+
args[-1])
6231+
args = (*args[:-1], data)
62276232

62286233
X, Y, C, shading = self._pcolorargs('pcolor', *args, shading=shading,
62296234
kwargs=kwargs)
@@ -6261,7 +6266,7 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
62616266
coords = stack([X, Y], axis=-1)
62626267

62636268
collection = mcoll.PolyQuadMesh(
6264-
coords, array=C, colorizer=colorizer,
6269+
coords, array=C, colorizer=colorizer_obj,
62656270
alpha=alpha, **kwargs)
62666271
collection._scale_norm(norm, vmin, vmax)
62676272

@@ -6496,6 +6501,10 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
64966501
cmap=cmap,
64976502
colorizer=colorizer)
64986503
if colorizer_obj.norm.n_input > 1:
6504+
# Valid call signatures for pcolor are with args = (C) or args = (X, Y, C)
6505+
# If provided, _pcolorargs will check that X, Y and C have the same shape.
6506+
# Before this check, we need to convert C from shape (K, N, M), where K is
6507+
# the number of variates, to (N, M) with a data type with K fields.
64996508
data = mcolorizer._ensure_multivariate_data(colorizer_obj.norm.n_input,
65006509
args[-1])
65016510
args = (*args[:-1], data)

lib/matplotlib/colorizer.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ def _set_cmap(self, cmap):
226226
if self.norm.n_output != cmap_obj.n_variates:
227227
raise ValueError(f"The colormap {cmap} does not support "
228228
f"{self.norm.n_output} variates as required by "
229-
"the norm on this Colorizer.")
229+
f"the {type(self.norm)} on this Colorizer.")
230230
self._cmap = cmap_obj
231231
if not in_init:
232232
self.changed() # Things are not set up properly yet.
@@ -738,13 +738,7 @@ def _ensure_norm(norm, n_variates=1):
738738
if norm is None:
739739
norm = colors.Normalize()
740740
elif isinstance(norm, str):
741-
try:
742-
scale_cls = scale._scale_mapping[norm]
743-
except KeyError:
744-
raise ValueError(
745-
"Invalid norm str name; the following values are "
746-
f"supported: {', '.join(scale._scale_mapping)}"
747-
) from None
741+
scale_cls = scale._get_scale_cls_from_str(norm)
748742
norm = _auto_norm_from_scale(scale_cls)()
749743
return norm
750744
else: # n_variates > 1

lib/matplotlib/colors.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3128,13 +3128,7 @@ def __init__(self, norms, vmin=None, vmax=None, clip=False):
31283128
if n is None:
31293129
norms[i] = Normalize()
31303130
elif isinstance(n, str):
3131-
try:
3132-
scale_cls = scale._scale_mapping[n]
3133-
except KeyError:
3134-
raise ValueError(
3135-
"Invalid norm str name; the following values are "
3136-
f"supported: {', '.join(scale._scale_mapping)}"
3137-
) from None
3131+
scale_cls = scale._get_scale_cls_from_str(n)
31383132
norms[i] = mpl.colorizer._auto_norm_from_scale(scale_cls)()
31393133

31403134
# Convert the list of norms to a tuple to make it immutable.
@@ -3245,9 +3239,8 @@ def __call__(self, value, clip=None):
32453239
"""
32463240
if clip is None:
32473241
clip = self.clip
3248-
else:
3249-
if not np.iterable(clip):
3250-
clip = [clip]*self.n_input
3242+
elif not np.iterable(clip):
3243+
clip = [clip]*self.n_input
32513244

32523245
value = self._iterable_variates_in_data(value, self.n_input)
32533246
result = [n(v, clip=c) for n, v, c in zip(self.norms, value, clip)]

lib/matplotlib/scale.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,35 @@ def get_scale_names():
713713
return sorted(_scale_mapping)
714714

715715

716+
def _get_scale_cls_from_str(scale_as_str):
717+
"""
718+
Returns the scale class from a string.
719+
720+
Used in the creation of norms from a string to ensure a reasonable error
721+
in the case where an invalid string is used. This cannot use
722+
`_api.check_getitem()`, because the norm keyword accepts arguments
723+
other than strings.
724+
725+
Parameters
726+
----------
727+
scale_as_str : string
728+
A string corresponding to a scale
729+
730+
Returns
731+
-------
732+
A subclass of ScaleBase.
733+
734+
"""
735+
try:
736+
scale_cls = _scale_mapping[scale_as_str]
737+
except KeyError:
738+
raise ValueError(
739+
"Invalid norm str name; the following values are "
740+
f"supported: {', '.join(_scale_mapping)}"
741+
) from None
742+
return scale_cls
743+
744+
716745
def scale_factory(scale, axis, **kwargs):
717746
"""
718747
Return a scale class by name.
535 Bytes
Loading
483 Bytes
Loading

lib/matplotlib/tests/test_multivariate_axes.py

Lines changed: 9 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from matplotlib.testing.decorators import (image_comparison,
55
remove_ticks_and_titles)
66
import matplotlib.colors as mcolors
7+
from matplotlib import cbook
78
import matplotlib as mpl
89
import pytest
910
import re
@@ -14,7 +15,7 @@ def test_bivariate_visualizations():
1415
x_0 = np.arange(25, dtype='float32').reshape(5, 5) % 5
1516
x_1 = np.arange(25, dtype='float32').reshape(5, 5).T % 5
1617

17-
fig, axes = plt.subplots(1, 6, figsize=(10, 2))
18+
fig, axes = plt.subplots(1, 7, figsize=(12, 2))
1819

1920
axes[0].imshow((x_0, x_1), cmap='BiPeak', interpolation='nearest')
2021
axes[1].matshow((x_0, x_1), cmap='BiPeak')
@@ -24,7 +25,8 @@ def test_bivariate_visualizations():
2425
x = np.arange(5)
2526
y = np.arange(5)
2627
X, Y = np.meshgrid(x, y)
27-
axes[4].pcolormesh(X, Y, (x_0, x_1), cmap='BiPeak')
28+
axes[4].pcolor(X, Y, (x_0, x_1), cmap='BiPeak')
29+
axes[5].pcolormesh(X, Y, (x_0, x_1), cmap='BiPeak')
2830

2931
patches = [
3032
mpl.patches.Wedge((.3, .7), .1, 0, 360), # Full circle
@@ -36,7 +38,7 @@ def test_bivariate_visualizations():
3638
colors_1 = np.arange(len(patches)) % 2
3739
p = mpl.collections.PatchCollection(patches, cmap='BiPeak', alpha=0.5)
3840
p.set_array((colors_0, colors_1))
39-
axes[5].add_collection(p)
41+
axes[6].add_collection(p)
4042

4143
remove_ticks_and_titles(fig)
4244

@@ -47,7 +49,7 @@ def test_multivariate_visualizations():
4749
x_1 = np.arange(25, dtype='float32').reshape(5, 5).T % 5
4850
x_2 = np.arange(25, dtype='float32').reshape(5, 5) % 6
4951

50-
fig, axes = plt.subplots(1, 6, figsize=(10, 2))
52+
fig, axes = plt.subplots(1, 7, figsize=(12, 2))
5153

5254
axes[0].imshow((x_0, x_1, x_2), cmap='3VarAddA', interpolation='nearest')
5355
axes[1].matshow((x_0, x_1, x_2), cmap='3VarAddA')
@@ -57,7 +59,8 @@ def test_multivariate_visualizations():
5759
x = np.arange(5)
5860
y = np.arange(5)
5961
X, Y = np.meshgrid(x, y)
60-
axes[4].pcolormesh(X, Y, (x_0, x_1, x_2), cmap='3VarAddA')
62+
axes[4].pcolor(X, Y, (x_0, x_1, x_2), cmap='3VarAddA')
63+
axes[5].pcolormesh(X, Y, (x_0, x_1, x_2), cmap='3VarAddA')
6164

6265
patches = [
6366
mpl.patches.Wedge((.3, .7), .1, 0, 360), # Full circle
@@ -70,7 +73,7 @@ def test_multivariate_visualizations():
7073
colors_2 = np.arange(len(patches)) % 3
7174
p = mpl.collections.PatchCollection(patches, cmap='3VarAddA', alpha=0.5)
7275
p.set_array((colors_0, colors_1, colors_2))
73-
axes[5].add_collection(p)
76+
axes[6].add_collection(p)
7477

7578
remove_ticks_and_titles(fig)
7679

@@ -625,52 +628,8 @@ def test_cmap_error():
625628
)):
626629
mpl.collections.PatchCollection([], cmap='not_a_cmap')
627630

628-
if 0:
629-
def test_artist_format_cursor_data_multivar():
630-
631-
X = np.zeros((3, 3))
632-
X[0, 0] = 0.9
633-
X[0, 1] = 0.99
634-
X[0, 2] = 0.999
635-
X[1, 0] = -1
636-
X[1, 1] = 0
637-
X[1, 2] = 1
638-
X[2, 0] = 0.09
639-
X[2, 1] = 0.009
640-
X[2, 2] = 0.0009
641-
642-
labels_list = [
643-
"[0.9, 0.0]",
644-
"[1., 0.0]",
645-
"[1., 0.0]",
646-
"[-1.0, 0.0]",
647-
"[0.0, 0.0]",
648-
"[1.0, 0.0]",
649-
"[0.09, 0.0]",
650-
"[0.009, 0.0]",
651-
"[0.0009, 0.0]",
652-
]
653-
654-
pos = [[0, 0], [1, 0], [2, 0],
655-
[0, 1], [1, 1], [2, 1],
656-
[0, 2], [1, 2], [2, 2]]
657-
658-
from matplotlib.backend_bases import MouseEvent
659-
660-
for cmap in ['BiOrangeBlue', '2VarAddA']:
661-
fig, ax = plt.subplots()
662-
norm = mpl.colors.BoundaryNorm(np.linspace(-1, 1, 20), 256)
663-
data = (X, np.zeros(X.shape))
664-
im = ax.imshow(data, cmap=cmap, norm=(norm, None))
665-
666-
for v, text in zip(pos, labels_list):
667-
xdisp, ydisp = ax.transData.transform(v)
668-
event = MouseEvent('motion_notify_event', fig.canvas, xdisp, ydisp)
669-
assert im.format_cursor_data(im.get_cursor_data(event)) == text
670-
671631

672632
def test_multivariate_safe_masked_invalid():
673-
from matplotlib import cbook
674633
dt = np.dtype('float32, float32').newbyteorder('>')
675634
x = np.zeros(2, dtype=dt)
676635
x['f0'][0] = np.nan

0 commit comments

Comments
 (0)