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

Skip to content
Open
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
1 change: 1 addition & 0 deletions doc/api/colors_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Multivariate Colormaps
BivarColormap
SegmentedBivarColormap
BivarColormapFromImage
MultivarColormap

Other classes
-------------
Expand Down
4 changes: 4 additions & 0 deletions doc/api/figure_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ Annotating
:nosignatures:

Figure.colorbar
Figure.colorbar_bivar
Figure.colorbar_multivar
Figure.legend
Figure.text
Figure.suptitle
Expand Down Expand Up @@ -254,6 +256,8 @@ Annotating
:nosignatures:

SubFigure.colorbar
SubFigure.colorbar_bivar
SubFigure.colorbar_multivar
SubFigure.legend
SubFigure.text
SubFigure.suptitle
Expand Down
2 changes: 2 additions & 0 deletions doc/api/pyplot_summary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ Colormapping

clim
colorbar
colorbar_bivar
colorbar_multivar
gci
sci
get_cmap
Expand Down
63 changes: 46 additions & 17 deletions lib/matplotlib/_constrained_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,12 +398,18 @@ def make_layout_margins(layoutgrids, fig, renderer, *, w_pad=0, h_pad=0,
# make margin for colorbars. These margins go in the
# padding margin, versus the margin for Axes decorators.
for cbax in ax._colorbars:
if cbax._colorbar_info["type"] == "MultivarColorbar":
# a matplotlib.colorbar.MultivarColorbar object
fig = cbax.axes[0].get_figure(root=False)
tightbbox = cbax.get_tightbbox(renderer, for_layout_only=True)
cbbbox = tightbbox.transformed(fig.transFigure.inverted())
else:
cbpos, cbbbox = get_pos_and_bbox(cbax, renderer)
# note pad is a fraction of the parent width...
pad = colorbar_get_pad(layoutgrids, cbax)
# colorbars can be child of more than one subplot spec:
cbp_rspan, cbp_cspan = get_cb_parent_spans(cbax)
loc = cbax._colorbar_info['location']
cbpos, cbbbox = get_pos_and_bbox(cbax, renderer)
if loc == 'right':
if cbp_cspan.stop == ss.colspan.stop:
# only increase if the colorbar is on the right edge
Expand Down Expand Up @@ -700,7 +706,7 @@ def reposition_colorbar(layoutgrids, cbax, renderer, *, offset=None, compress=Fa
Parameters
----------
layoutgrids : dict
cbax : `~matplotlib.axes.Axes`
cbax : `~matplotlib.colorbar.MultiColorbars` or `~matplotlib.axes.Axes`
Axes for the colorbar.
renderer : `~matplotlib.backend_bases.RendererBase` subclass.
The renderer to use.
Expand All @@ -710,22 +716,30 @@ def reposition_colorbar(layoutgrids, cbax, renderer, *, offset=None, compress=Fa
compress : bool
Whether we're in compressed layout mode.
"""
cb_info = cbax._colorbar_info
if cb_info["type"] == "MultivarColorbar":
multi_cbar = cbax
cbaxes = multi_cbar.axes
multi = True
else:
multi = False
cbaxes = [cbax]

parents = cbax._colorbar_info['parents']
parents = cb_info['parents']
gs = parents[0].get_gridspec()
fig = cbax.get_figure(root=False)
fig = cbaxes[0].get_figure(root=False)
trans_fig_to_subfig = fig.transFigure - fig.transSubfigure

cb_rspans, cb_cspans = get_cb_parent_spans(cbax)
bboxparent = layoutgrids[gs].get_bbox_for_cb(rows=cb_rspans,
cols=cb_cspans)
pb = layoutgrids[gs].get_inner_bbox(rows=cb_rspans, cols=cb_cspans)

location = cbax._colorbar_info['location']
anchor = cbax._colorbar_info['anchor']
fraction = cbax._colorbar_info['fraction']
aspect = cbax._colorbar_info['aspect']
shrink = cbax._colorbar_info['shrink']
location = cb_info['location']
anchor = cb_info['anchor']
fraction = cb_info['fraction']
aspect = cb_info['aspect']
shrink = cb_info['shrink']

# For colorbars with a single parent in compressed layout,
# use the actual visual size of the parent axis after apply_aspect()
Expand All @@ -745,14 +759,20 @@ def reposition_colorbar(layoutgrids, cbax, renderer, *, offset=None, compress=Fa
# Keep the pb x-coordinates but use actual y-coordinates
pb = Bbox.from_extents(pb.x0, actual_pos_fig.y0,
pb.x1, actual_pos_fig.y1)
elif location in ('top', 'bottom'):
else: # location in ('top', 'bottom'):
# For horizontal colorbars, use the actual parent bbox width
# for colorbar sizing
# Keep the pb y-coordinates but use actual x-coordinates
pb = Bbox.from_extents(actual_pos_fig.x0, pb.y0,
actual_pos_fig.x1, pb.y1)

cbpos, cbbbox = get_pos_and_bbox(cbax, renderer)
if multi:
tightbbox = martist._get_tightbbox_for_layout_only(multi_cbar, renderer)
cbbbox = tightbbox.transformed(fig.transFigure.inverted())
cbpos = multi_cbar._get_original_position()
cbpos = cbpos.transformed(fig.transSubfigure - fig.transFigure)
else:
cbpos, cbbbox = get_pos_and_bbox(cbax, renderer)

# Colorbar gets put at extreme edge of outer bbox of the subplotspec
# It needs to be moved in by: 1) a pad 2) its "margin" 3) by
Expand All @@ -763,6 +783,8 @@ def reposition_colorbar(layoutgrids, cbax, renderer, *, offset=None, compress=Fa
pbcb = pb.shrunk(fraction, shrink).anchored(anchor, pb)
# The colorbar is at the left side of the parent. Need
# to translate to right (or left)
if multi:
pbcb.x1 = pbcb.x0 + cbbbox.width
if location == 'right':
lmargin = cbpos.x0 - cbbbox.x0
dx = bboxparent.x1 - pbcb.x0 + offset['right']
Expand All @@ -777,6 +799,8 @@ def reposition_colorbar(layoutgrids, cbax, renderer, *, offset=None, compress=Fa
pbcb = pbcb.translated(dx, 0)
else: # horizontal axes:
pbcb = pb.shrunk(shrink, fraction).anchored(anchor, pb)
if multi:
pbcb.y1 = pbcb.y0 + cbbbox.height
if location == 'top':
bmargin = cbpos.y0 - cbbbox.y0
dy = bboxparent.y1 - pbcb.y0 + offset['top']
Expand All @@ -790,14 +814,19 @@ def reposition_colorbar(layoutgrids, cbax, renderer, *, offset=None, compress=Fa
offset['bottom'] += cbbbox.height + cbpad
pbcb = pbcb.translated(0, dy)

pbcb = trans_fig_to_subfig.transform_bbox(pbcb)
cbax.set_transform(fig.transSubfigure)
cbax._set_position(pbcb)
cbax.set_anchor(anchor)
if location in ['bottom', 'top']:
aspect = 1 / aspect
cbax.set_box_aspect(aspect)
cbax.set_aspect('auto')
if multi:
new_bboxs = multi_cbar._get_tight_packing_inside(pbcb)
else:
new_bboxs = [pbcb]
for cbax, new_bbox in zip(cbaxes, new_bboxs):
transformed_bbox = trans_fig_to_subfig.transform_bbox(new_bbox)
cbax.set_transform(fig.transSubfigure)
cbax._set_position(transformed_bbox)
cbax.set_anchor(anchor)
cbax.set_box_aspect(aspect)
cbax.set_aspect('auto')
return offset


Expand Down
67 changes: 48 additions & 19 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6175,6 +6175,7 @@ def imshow(self, X, cmap=None, norm=None, *, aspect=None,
- (M, N): an image with scalar data. The values are mapped to
colors using normalization and a colormap. See parameters *norm*,
*cmap*, *vmin*, *vmax*.
- (K, M, N): if coupled with a cmap that supports K scalars
- (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
- (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
i.e. including transparency.
Expand All @@ -6184,15 +6185,16 @@ def imshow(self, X, cmap=None, norm=None, *, aspect=None,

Out-of-range RGB(A) values are clipped.

%(cmap_doc)s

%(multi_cmap_doc)s

This parameter is ignored if *X* is RGB(A).

%(norm_doc)s
%(multi_norm_doc)s

This parameter is ignored if *X* is RGB(A).

%(vmin_vmax_doc)s
%(multi_vmin_vmax_doc)s

This parameter is ignored if *X* is RGB(A).

Expand Down Expand Up @@ -6271,6 +6273,10 @@ def imshow(self, X, cmap=None, norm=None, *, aspect=None,
See :doc:`/gallery/images_contours_and_fields/image_antialiasing` for
a discussion of image antialiasing.

When using a `~matplotlib.colors.BivarColormap` or
`~matplotlib.colors.MultivarColormap`, 'data' is the only valid
interpolation_stage.

alpha : float or array-like, optional
The alpha blending value, between 0 (transparent) and 1 (opaque).
If *alpha* is an array, the alpha blending values are applied pixel
Expand Down Expand Up @@ -6376,6 +6382,7 @@ def imshow(self, X, cmap=None, norm=None, *, aspect=None,
if aspect is not None:
self.set_aspect(aspect)

X = mcolorizer._ensure_multivariate_data(X, im.norm.n_components)
im.set_data(X)
im.set_alpha(alpha)
if im.get_clip_path() is None:
Expand Down Expand Up @@ -6531,9 +6538,10 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,

Parameters
----------
C : 2D array-like
C : 2D (M, N) or 3D (K, M, N) array-like
The color-mapped values. Color-mapping is controlled by *cmap*,
*norm*, *vmin*, and *vmax*.
*norm*, *vmin*, and *vmax*. 3D arrays are supported only if the
cmap supports K channels.

X, Y : array-like, optional
The coordinates of the corners of quadrilaterals of a pcolormesh::
Expand Down Expand Up @@ -6578,11 +6586,11 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
See :doc:`/gallery/images_contours_and_fields/pcolormesh_grids`
for more description.

%(cmap_doc)s
%(multi_cmap_doc)s

%(norm_doc)s
%(multi_norm_doc)s

%(vmin_vmax_doc)s
%(multi_vmin_vmax_doc)s

%(colorizer_doc)s

Expand Down Expand Up @@ -6657,8 +6665,19 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
if shading is None:
shading = mpl.rcParams['pcolor.shading']
shading = shading.lower()
X, Y, C, shading = self._pcolorargs('pcolor', *args, shading=shading,
kwargs=kwargs)

mcolorizer.ColorizingArtist._check_exclusionary_keywords(colorizer,
vmin=vmin, vmax=vmax,
norm=norm, cmap=cmap)
if colorizer is None:
colorizer = mcolorizer.Colorizer(cmap=cmap, norm=norm)

C = mcolorizer._ensure_multivariate_data(args[-1],
colorizer.cmap.n_variates)

X, Y, C, shading = self._pcolorargs('pcolor', *args[:-1], C,
shading=shading, kwargs=kwargs)

linewidths = (0.25,)
if 'linewidth' in kwargs:
kwargs['linewidths'] = kwargs.pop('linewidth')
Expand Down Expand Up @@ -6693,9 +6712,7 @@ def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
coords = stack([X, Y], axis=-1)

collection = mcoll.PolyQuadMesh(
coords, array=C, cmap=cmap, norm=norm, colorizer=colorizer,
alpha=alpha, **kwargs)
collection._check_exclusionary_keywords(colorizer, vmin=vmin, vmax=vmax)
coords, array=C, colorizer=colorizer, alpha=alpha, **kwargs)
collection._scale_norm(norm, vmin, vmax)

coords = coords.reshape(-1, 2) # flatten the grid structure; keep x, y
Expand Down Expand Up @@ -6733,6 +6750,7 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
- (M, N) or M*N: a mesh with scalar data. The values are mapped to
colors using normalization and a colormap. See parameters *norm*,
*cmap*, *vmin*, *vmax*.
- (K, M, N): if coupled with a cmap that supports K scalars
- (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
- (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
i.e. including transparency.
Expand Down Expand Up @@ -6767,11 +6785,11 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
expanded as needed into the appropriate 2D arrays, making a
rectangular grid.

%(cmap_doc)s
%(multi_cmap_doc)s

%(norm_doc)s
%(multi_norm_doc)s

%(vmin_vmax_doc)s
%(multi_vmin_vmax_doc)s

%(colorizer_doc)s

Expand Down Expand Up @@ -6897,16 +6915,24 @@ def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
shading = mpl._val_or_rc(shading, 'pcolor.shading').lower()
kwargs.setdefault('edgecolors', 'none')

X, Y, C, shading = self._pcolorargs('pcolormesh', *args,
mcolorizer.ColorizingArtist._check_exclusionary_keywords(colorizer,
vmin=vmin, vmax=vmax,
norm=norm, cmap=cmap)
if colorizer is None:
colorizer = mcolorizer.Colorizer(cmap=cmap, norm=norm)

C = mcolorizer._ensure_multivariate_data(args[-1],
colorizer.cmap.n_variates)

X, Y, C, shading = self._pcolorargs('pcolormesh', *args[:-1], C,
shading=shading, kwargs=kwargs)
coords = np.stack([X, Y], axis=-1)

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

collection = mcoll.QuadMesh(
coords, antialiased=antialiased, shading=shading,
array=C, cmap=cmap, norm=norm, colorizer=colorizer, alpha=alpha, **kwargs)
collection._check_exclusionary_keywords(colorizer, vmin=vmin, vmax=vmax)
array=C, colorizer=colorizer, alpha=alpha, **kwargs)
collection._scale_norm(norm, vmin, vmax)

coords = coords.reshape(-1, 2) # flatten the grid structure; keep x, y
Expand Down Expand Up @@ -8848,6 +8874,9 @@ def matshow(self, Z, **kwargs):

"""
Z = np.asanyarray(Z)
if Z.ndim != 2:
if Z.ndim != 3 or Z.shape[2] not in (1, 3, 4):
raise TypeError(f"Invalid shape {Z.shape} for image data")
kw = {'origin': 'upper',
'interpolation': 'nearest',
'aspect': 'equal', # (already the imshow default)
Expand Down
Loading
Loading