8000 colorizer keyword on plotting funcitons · matplotlib/matplotlib@b9fb9dd · GitHub
[go: up one dir, main page]

Skip to content

Commit b9fb9dd

Browse files
committed
colorizer keyword on plotting funcitons
1 parent f2a0ba1 commit b9fb9dd

File tree

7 files changed

+186
-39
lines changed

7 files changed

+186
-39
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4696,7 +4696,7 @@ def invalid_shape_exception(csize, xsize):
46964696
label_namer="y")
46974697
@_docstring.interpd
46984698
def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
4699-
vmin=None, vmax=None, alpha=None, linewidths=None, *,
4699+
vmin=None, vmax=None, colorizer=None, alpha=None, linewidths=None, *,
47004700
edgecolors=None, plotnonfinite=False, **kwargs):
47014701
"""
47024702
A scatter plot of *y* vs. *x* with varying marker size and/or color.
@@ -4765,6 +4765,10 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
47654765
47664766
This parameter is ignored if *c* is RGB(A).
47674767
4768+
%(colorizer_doc)s
4769+
4770+
This parameter is ignored if *c* is RGB(A).
4771+
47684772
alpha : float, default: None
47694773
The alpha blending value, between 0 (transparent) and 1 (opaque).
47704774
@@ -4938,9 +4942,13 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
49384942
)
49394943
collection.set_transform(mtransforms.IdentityTransform())
49404944
if colors is None:
4945+
if colorizer:
4946+
collection._set_colorizer_check_keywords(colorizer, cmap, norm,
4947+
vmin, vmax)
4948+
else:
4949+
collection.set_cmap(cmap)
4950+
collection.set_norm(norm)
49414951
collection.set_array(c)
4942-
collection.set_cmap(cmap)
4943-
collection.set_norm(norm)
49444952
collection._scale_norm(norm, vmin, vmax)
49454953
else:
49464954
extra_kwargs = {
@@ -4975,7 +4983,7 @@ def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
49754983
@_docstring.dedent_interpd
49764984
def hexbin(self, x, y, C=None, gridsize=100, bins=None,
49774985
xscale='linear', yscale='linear', extent=None,
4978-
cmap=None, norm=None, vmin=None, vmax=None,
4986+
cmap=None, norm=None, vmin=None, vmax=None, colorizer=None,
49794987
alpha=None, linewidths=None, edgecolors='face',
49804988
reduce_C_function=np.mean, mincnt=None, marginals=False,
49814989
**kwargs):
@@ -5089,6 +5097,8 @@ def hexbin(self, x, y, C=None, gridsize=100, bins=None,
50895097
50905098
%(vmin_vmax_doc)s
50915099
5100+
%(colorizer_doc)s
5101+
50925102
alpha : float between 0 and 1, optional
50935103
The alpha blending value, between 0 (transparent) and 1 (opaque).
50945104
@@ -5291,9 +5301,12 @@ def reduce_C_function(C: array) -> float
52915301
bins = np.sort(bins)
52925302
accum = bins.searchsorted(accum)
52935303

5304+
if colorizer:
5305+
collection._set_colorizer_check_keywords(colorizer, cmap, norm, vmin, vmax)
5306+
else:
5307+
collection.set_cmap(cmap)
5308+
collection.set_norm(norm)
52945309
collection.set_array(accum)
5295-
collection.set_cmap(cmap)
5296-
collection.set_norm(norm)
52975310
collection.set_alpha(alpha)
52985311
collection._internal_update(kwargs)
52995312
collection._scale_norm(norm, vmin, vmax)
@@ -5728,7 +5741,7 @@ def fill_betweenx(self, y, x1, x2=0, where=None,
57285741
@_docstring.interpd
57295742
def imshow(self, X, cmap=None, norm=None, *, aspect=None,
57305743
interpolation=None, alpha=None,
5731-
vmin=None, vmax=None, origin=None, extent=None,
5744+
vmin=None, vmax=None, colorizer=None, origin=None, extent=None,
57325745
interpolation_stage=None, filternorm=True, filterrad=4.0,
57335746
resample=None, url=None, **kwargs):
57345747
"""
@@ -5776,6 +5789,10 @@ def imshow(self, X, cmap=None, norm=None, *, aspect=None,
57765789
57775790
This parameter is ignored if *X* is RGB(A).
57785791
5792+
%(colorizer_doc)s
5793+
5794+
This parameter is ignored if *X* is RGB(A).
5795+
57795796
aspect : {'equal', 'auto'} or float or None, default: None
57805797
The aspect ratio of the Axes. This parameter is particularly
57815798
relevant for images since it determines whether data pixels are
@@ -5938,7 +5955,7 @@ def imshow(self, X, cmap=None, norm=None, *, aspect=None,
59385955
`~matplotlib.pyplot.imshow` expects RGB images adopting the straight
59395956
(unassociated) alpha representation.
59405957
"""
5941-
im = mimage.AxesImage(self, cmap=cmap, norm=norm,
5958+
im = mimage.AxesImage(self, cmap=cmap, norm=norm, colorizer=colorizer,
59425959
interpolation=interpolation, origin=origin,
59435960
extent=extent, filternorm=filternorm,
59445961
filterrad=filterrad, resample=resample,
@@ -6082,7 +6099,7 @@ def _interp_grid(X):
60826099
@_preprocess_data()
60836100
@_docstring.dedent_interpd
60846101
def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
6085-
vmin=None, vmax=None, **kwargs):
6102+
vmin=None, vmax=None, colorizer=None, **kwargs):
60866103
r"""
60876104
Create a pseudocolor plot with a non-regular rectangular grid.
60886105
@@ -6160,6 +6177,8 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
61606177
61616178
%(vmin_vmax_doc)s
61626179
6180+
%(colorizer_doc)s
6181+
61636182
edgecolors : {'none', None, 'face', color, color sequence}, optional
61646183
The color of the edges. Defaults to 'none'. Possible values:
61656184
@@ -6267,7 +6286,8 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
62676286
coords = stack([X, Y], axis=-1)
62686287

62696288
collection = mcoll.PolyQuadMesh(
6270-
coords, array=C, cmap=cmap, norm=norm, alpha=alpha, **kwargs)
6289+
coords, array=C, cmap=cmap, norm=norm, colorizer=colorizer,
6290+
alpha=alpha, **kwargs)
62716291
collection._scale_norm(norm, vmin, vmax)
62726292

62736293
# Transform from native to data coordinates?
@@ -6299,7 +6319,8 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
62996319
@_preprocess_data()
63006320
@_docstring.dedent_interpd
63016321
def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
6302-
vmax=None, shading=None, antialiased=False, **kwargs):
6322+
vmax=None, colorizer=None, shading=None, antialiased=False,
6323+
**kwargs):
63036324
"""
63046325
Create a pseudocolor plot with a non-regular rectangular grid.
63056326
@@ -6368,6 +6389,8 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
63686389
63696390
%(vmin_vmax_doc)s
63706391
6392+
%(colorizer_doc)s
6393+
63716394
edgecolors : {'none', None, 'face', color, color sequence}, optional
63726395
The color of the edges. Defaults to 'none'. Possible values:
63736396
@@ -6497,7 +6520,7 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
64976520

64986521
collection = mcoll.QuadMesh(
64996522
coords, antialiased=antialiased, shading=shading,
6500-
array=C, cmap=cmap, norm=norm, alpha=alpha, **kwargs)
6523+
array=C, cmap=cmap, norm=norm, colorizer=colorizer, alpha=alpha, **kwargs)
65016524
collection._scale_norm(norm, vmin, vmax)
65026525

65036526
coords = coords.reshape(-1, 2) # flatten the grid structure; keep x, y
@@ -6526,7 +6549,7 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
65266549
@_preprocess_data()
65276550
@_docstring.dedent_interpd
65286551
def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
6529-
vmax=None, **kwargs):
6552+
vmax=None, colorizer=None, **kwargs):
65306553
"""
65316554
Create a pseudocolor plot with a non-regular rectangular grid.
65326555
@@ -6612,6 +6635,10 @@ def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
66126635
66136636
This parameter is ignored if *C* is RGB(A).
66146637
6638+
%(colorizer_doc)s
6639+
6640+
This parameter is ignored if *C* is RGB(A).
6641+
66156642
alpha : float, default: None
66166643
The alpha blending value, between 0 (transparent) and 1 (opaque).
66176644
@@ -6675,7 +6702,7 @@ def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
66756702
raise ValueError("C must be 2D or 3D")
66766703
collection = mcoll.QuadMesh(
66776704
coords, array=C,
6678-
alpha=alpha, cmap=cmap, norm=norm,
6705+
alpha=alpha, cmap=cmap, norm=norm, colorizer=colorizer,
66796706
antialiased=False, edgecolors="none")
66806707
self.add_collection(collection, autolim=False)
66816708
xl, xr, yb, yt = x.min(), x.max(), y.min(), y.max()
@@ -6685,15 +6712,15 @@ def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
66856712
extent = xl, xr, yb, yt = x[0], x[-1], y[0], y[-1]
66866713
if style == "image":
66876714
im = mimage.AxesImage(
6688-
self, cmap=cmap, norm=norm,
6715+
self, cmap=cmap, norm=norm, colorizer=colorizer,
66896716
data=C, alpha=alpha, extent=extent,
66906717
interpolation='nearest', origin='lower',
66916718
**kwargs)
66926719
elif style == "pcolorimage":
66936720
im = mimage.PcolorImage(
66946721
self, x, y, C,
6695-
cmap=cmap, norm=norm, alpha=alpha, extent=extent,
6696-
**kwargs)
6722+
cmap=cmap, norm=norm, colorizer=colorizer, alpha=alpha,
6723+
extent=extent, **kwargs)
66976724
self.add_image(im)
66986725
ret = im
66996726

@@ -7426,6 +7453,8 @@ def hist2d(self, x, y, bins=10, range=None, density=False, weights=None,
74267453
74277454
%(vmin_vmax_doc)s
74287455
7456+
%(colorizer_doc)s
7457+
74297458
alpha : ``0 <= scalar <= 1`` or ``None``, optional
74307459
The alpha blending value.
74317460

lib/matplotlib/collections.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
import numpy as np
1818

1919
import matplotlib as mpl
20-
from . import (_api, _path, artist, cbook, colorizer, colors as mcolors, _docstring,
21-
hatch as mhatch, lines as mlines, path as mpath, transforms)
20+
from . import (_api, _path, artist, cbook, colorizer as mcolorizer, colors as mcolors,
21+
_docstring, hatch as mhatch, lines as mlines, path as mpath, transforms)
2222
from ._enums import JoinStyle, CapStyle
2323

2424

@@ -32,7 +32,7 @@
3232
"linewidth": ["linewidths", "lw"],
3333
"offset_transform": ["transOffset"],
3434
})
35-
class Collection(colorizer.ColorizingArtist):
35+
class Collection(mcolorizer.ColorizingArtist):
3636
r"""
3737
Base class for Collections. Must be subclassed to be usable.
3838
@@ -87,6 +87,7 @@ def __init__(self, *,
8787
offset_transform=None,
8888
norm=None, # optional for ScalarMappable
8989
cmap=None, # ditto
90+
colorizer=None,
9091
pickradius=5.0,
9192
hatch=None,
9293
urls=None,
@@ -156,7 +157,8 @@ def __init__(self, *,
156157
``Collection.set_{key}(val)`` for each key-value pair in *kwargs*.
157158
"""
158159

159-
colorizer.ColorizingArtist.__init__(self, colorizer._get_colorizer(cmap, norm))
160+
mcolorizer.ColorizingArtist.__init__(self, mcolorizer._get_colorizer(cmap, norm,
161+
colorizer))
160162
# list of un-scaled dash patterns
161163
# this is needed scaling the dash pattern by linewidth
162164
self._us_linestyles = [(0, None)]

lib/matplotlib/colorizer.py

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919
from numpy import ma
2020
import functools
2121
from matplotlib import _api, colors, cbook, scale, cm, artist
22+
import matplotlib as mpl
23+
24+
mpl._docstring.interpd.update(
25+
colorizer_doc="""\
26+
colorizer : `~matplotlib.colorizer.Colorizer` or None, default: None
27+
The Colorizer object used to map color to data. If None, a Colorizer
28+
object is created base on *norm* and *cmap*.""",
29+
)
2230

2331

2432
class Colorizer():
@@ -302,19 +310,15 @@ def clip(self, clip):
302310
self.norm.clip = clip
303311

304312

305-
def _get_colorizer(cmap, norm):
313+
def _get_colorizer(cmap, norm, colorizer):
306314
"""
307315
Passes or creates a Colorizer object.
308-
309-
Allows users to pass a Colorizer as the norm keyword
310-
where a artist.ColorizingArtist is used as the artist.
311-
If a Colorizer object is not passed, a Colorizer is created.
312316
"""
313-
if isinstance(norm, Colorizer):
314-
if cmap:
315-
raise ValueError("Providing a `cm.Colorizer` as the norm while "
316-
"at the same time providing a `cmap` is not supported.")
317-
return norm
317+
if colorizer and isinstance(colorizer, Colorizer):
318+
if cmap or norm:
319+
raise ValueError("Providing a `cm.Colorizer` while at the same time "
320+
"providing a `norm` or `cmap` is not supported.")
321+
return colorizer
318322
return Colorizer(cmap, norm)
319323

320324

@@ -479,7 +483,7 @@ def __init__(self, colorizer):
479483

480484
self._A = None
481485

482-
self.colorizer = colorizer
486+
self._colorizer = colorizer
483487
self._id_colorizer = self.colorizer.callbacks.connect('changed', self.changed)
484488
self.callbacks = cbook.CallbackRegistry(signals=["changed"])
485489

@@ -525,6 +529,32 @@ def changed(self):
525529
self.callbacks.process('changed')
526530
self.stale = True
527531

532+
@property
533+
def colorizer(self):
534+
return self._colorizer
535+
536+
@colorizer.setter
537+
def colorizer(self, cl):
538+
if isinstance(cl, Colorizer):
539+
self._colorizer.callbacks.disconnect(self._id_colorizer)
540+
self._colorizer = cl
541+
self._id_colorizer = cl.callbacks.connect('changed', self.changed)
542+
else:
543+
raise ValueError("colorizer must be a `Colorizer` object, not "
544+
f" {type(cl)}.")
545+
546+
def _set_colorizer_check_keywords(self, colorizer, cmap=None, norm=None,
547+
vmin=None, vmax=None):
548+
"""
549+
Raises a ValueError on incompatible keyword combinations
550+
"""
551+
if colorizer is not None:
552+
if cmap is None and norm is None and vmin is None and vmin is None:
553+
self.colorizer = colorizer
554+
else:
555+
raise ValueError("The `colorizer` keyword cannot be used simultaneously"
556+
" with `cmap`, `norm`, `vmin` or `vmax`.")
557+
528558

529559
def _auto_norm_from_scale(scale_cls):
530560
"""

0 commit comments

Comments
 (0)
0