8000 Multivariate plots for imshow, pcolor and pcolormesh · matplotlib/matplotlib@14e1205 · GitHub
[go: up one dir, main page]

Skip to content

Commit 14e1205

Browse files
committed
Multivariate plots for imshow, pcolor and pcolormesh
1 parent 8b99d37 commit 14e1205

22 files changed

+963
-70
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6208,6 +6208,21 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
62086208
if shading is None:
62096209
shading = mpl.rcParams['pcolor.shading']
62106210
shading = shading.lower()
6211+
6212+
mcolorizer.ColorizingArtist._check_exclusionary_keywords(colorizer,
6213+
vmin=vmin,
6214+
vmax=vmax)
6215+
6216+
# we need to get the colorizer object to know the number of
6217+
# n_variates that should exist in the array, we therefore get the
6218+
# colorizer here.
6219+
colorizer = mcolorizer.ColorizingArtist._get_colorizer(norm=norm,
6220+
cmap=cmap,
6221+
colorizer=colorizer)
6222+
if colorizer.norm.n_input > 1:
6223+
data = mcolorizer._ensure_multivariate_data(colorizer.norm.n_input, args[0])
6224+
args = (data, *args[1:])
6225+
62116226
X, Y, C, shading = self._pcolorargs('pcolor', *args, shading=shading,
62126227
kwargs=kwargs)
62136228
linewidths = (0.25,)
@@ -6244,9 +6259,8 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
62446259
coords = stack([X, Y], axis=-1)
62456260

62466261
collection = mcoll.PolyQuadMesh(
6247-
coords, array=C, cmap=cmap, norm=norm, colorizer=colorizer,
6262+
coords, array=C, colorizer=colorizer,
62486263
alpha=alpha, **kwargs)
6249-
collection._check_exclusionary_keywords(colorizer, vmin=vmin, vmax=vmax)
62506264
collection._scale_norm(norm, vmin, vmax)
62516265

62526266
# Transform from native to data coordinates?
@@ -6469,6 +6483,20 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
64696483
shading = mpl._val_or_rc(shading, 'pcolor.shading').lower()
64706484
kwargs.setdefault('edgecolors', 'none')
64716485

6486+
mcolorizer.ColorizingArtist._check_exclusionary_keywords(colorizer,
6487+
vmin=vmin,
6488+
vmax=vmax)
6489+
# we need to get the colorizer object to know the number of
6490+
# n_variates that should exist in the array, we therefore get the
6491+
# colorizer here.
6492+
colorizer_obj = mcolorizer.ColorizingArtist._get_colorizer(norm=norm,
6493+
cmap=cmap,
6494+
colorizer=colorizer)
6495+
if colorizer_obj.norm.n_input > 1:
6496+
data = mcolorizer._ensure_multivariate_data(colorizer_obj.norm.n_input,
6497+
args[-1])
6498+
args = (*args[:-1], data)
6499+
64726500
X, Y, C, shading = self._pcolorargs('pcolormesh', *args,
64736501
shading=shading, kwargs=kwargs)
64746502
coords = np.stack([X, Y], axis=-1)
@@ -6477,8 +6505,8 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
64776505

64786506
collection = mcoll.QuadMesh(
64796507
coords, antialiased=antialiased, shading=shading,
6480-
array=C, cmap=cmap, norm=norm, colorizer=colorizer, alpha=alpha, **kwargs)
6481-
collection._check_exclusionary_keywords(colorizer, vmin=vmin, vmax=vmax)
6508+
array=C, colorizer=colorizer_obj,
6509+
alpha=alpha, **kwargs)
64826510
collection._scale_norm(norm, vmin, vmax)
64836511

64846512
coords = coords.reshape(-1, 2) # flatten the grid structure; keep x, y

lib/matplotlib/cbook.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,17 @@ def safe_masked_invalid(x, copy=False):
690690
try:
691691
xm = np.ma.masked_where(~(np.isfinite(x)), x, copy=False)
692692
except TypeError:
693-
return x
693+
if len(x.dtype.descr) == 1:
694+
return x
695+
else:
696+
# in case of a dtype with multiple fields:
697+
try:
698+
mask = np.empty(x.shape, dtype=np.dtype('bool, '*len(x.dtype.descr)))
699+
for dd, dm in zip(x.dtype.descr, mask.dtype.descr):
700+
mask[dm[0]] = ~(np.isfinite(x[dd[0]]))
701+
xm = np.ma.array(x, mask=mask, copy=False)
702+
except TypeError:
703+
return x
694704
return xm
695705

696706

lib/matplotlib/cm.py

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -278,32 +278,3 @@ def get_cmap(name=None, lut=None):
278278
return _colormaps[name]
279279
else:
280280
return _colormaps[name].resampled(lut)
281-
282-
283-
def _ensure_cmap(cmap):
284-
"""
285-
Ensure that we have a `.Colormap` object.
286-
287-
For internal use to preserve type stability of errors.
288-
289-
Parameters
290-
----------
291-
cmap : None, str, Colormap
292-
293-
- if a `Colormap`, return it
294-
- if a string, look it up in mpl.colormaps
295-
- if None, look up the default color map in mpl.colormaps
296-
297-
Returns
298-
-------
299-
Colormap
300-
301-
"""
302-
if isinstance(cmap, colors.Colormap):
303-
return cmap
304-
cmap_name = mpl._val_or_rc(cmap, "image.cmap")
305-
# use check_in_list to ensure type stability of the exception raised by
306-
# the internal usage of this (ValueError vs KeyError)
307-
if cmap_name not in _colormaps:
308-
_api.check_in_list(sorted(_colormaps), cmap=cmap_name)
309-
return mpl.colormaps[cmap_name]

lib/matplotlib/collections.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2528,10 +2528,16 @@ def _get_unmasked_polys(self):
25282528
arr = self.get_array()
25292529
if arr is not None:
25302530
arr = np.ma.getmaskarray(arr)
2531-
if arr.ndim == 3:
2531+
if self.norm.n_input > 1:
2532+
# multivar case
2533+
for a in mcolors.MultiNorm._iterable_variates_in_data(
2534+
arr, self.norm.n_input):
2535+
mask |= np.any(a, axis=0)
2536+
elif arr.ndim == 3:
25322537
# RGB(A) case
25332538
mask |= np.any(arr, axis=-1)
25342539
elif arr.ndim == 2:
2540+
# scalar case
25352541
mask |= arr
25362542
else:
25372543
mask |= arr.reshape(self._coordinates[:-1, :-1, :].shape[:2])

0 commit comments

Comments
 (0)
0