Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Update colorbar with new colorizer API#30008

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
trygvrad wants to merge1 commit intomatplotlib:main
base:main
Choose a base branch
Loading
fromtrygvrad:colorbar-with-colorizer
Open
Show file tree
Hide file tree
Changes fromall 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
105 changes: 70 additions & 35 deletionslib/matplotlib/colorbar.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,8 +16,9 @@
import numpy as np

import matplotlib as mpl
from matplotlib import _api, cbook, collections,cm,colors, contour, ticker
from matplotlib import _api, cbook, collections, colors, contour, ticker
import matplotlib.artist as martist
import matplotlib.colorizer as mcolorizer
import matplotlib.patches as mpatches
import matplotlib.path as mpath
import matplotlib.spines as mspines
Expand DownExpand Up@@ -199,12 +200,12 @@
Draw a colorbar in an existing Axes.

Typically, colorbars are created using `.Figure.colorbar` or
`.pyplot.colorbar` and associated with `.ScalarMappable`\s (such as an
`.pyplot.colorbar` and associated with `.ColorizingArtist`\s (such as an
`.AxesImage` generated via `~.axes.Axes.imshow`).

In order to draw a colorbar not associated with other elements in the
figure, e.g. when showing a colormap by itself, one can create an empty
`.ScalarMappable`, or directly pass *cmap* and *norm* instead of *mappable*
`.Colorizer`, or directly pass *cmap* and *norm* instead of *mappable*
to `Colorbar`.

Useful public methods are :meth:`set_label` and :meth:`add_lines`.
Expand DownExpand Up@@ -244,8 +245,8 @@
ax : `~matplotlib.axes.Axes`
The `~.axes.Axes` instance in which the colorbar is drawn.

mappable : `.ScalarMappable`
The mappable whose colormap and norm will be used.
mappable : `.ColorizingArtist` or `.Colorizer`
The mappableor colorizerwhose colormap and norm will be used.

To show the colors versus index instead of on a 0-1 scale, set the
mappable's norm to ``colors.NoNorm()``.
Expand DownExpand Up@@ -288,27 +289,33 @@
colorbar and at the right for a vertical.
"""
if mappable is None:
mappable =cm.ScalarMappable(norm=norm, cmap=cmap)
mappable =mcolorizer.Colorizer(norm=norm, cmap=cmap)

self.mappable = mappable
cmap = mappable.cmap
norm = mappable.norm
if isinstance(mappable, mcolorizer.Colorizer):
self._mappable = None
self._colorizer = mappable
else:
self._mappable = mappable
self._colorizer = mappable._colorizer
self._historic_norm = self.colorizer.norm

del mappable, cmap, norm

filled = True
if isinstance(mappable, contour.ContourSet):
cs = mappable
if isinstance(self.mappable, contour.ContourSet):
cs =self.mappable
alpha = cs.get_alpha()
boundaries = cs._levels
values = cs.cvalues
extend = cs.extend
filled = cs.filled
if ticks is None:
ticks = ticker.FixedLocator(cs.levels, nbins=10)
elif isinstance(mappable, martist.Artist):
alpha = mappable.get_alpha()
elif isinstance(self.mappable, martist.Artist):
alpha =self.mappable.get_alpha()

mappable.colorbar = self
mappable.colorbar_cid =mappable.callbacks.connect(
self.colorizer.colorbar = self
self.colorizer.colorbar_cid =self.colorizer.callbacks.connect(
'changed', self.update_normal)

location_orientation = _get_orientation_from_location(location)
Expand All@@ -332,18 +339,16 @@
self.ax._axes_locator = _ColorbarAxesLocator(self)

if extend is None:
if (not isinstance(mappable, contour.ContourSet)
and getattr(cmap, 'colorbar_extend', False) is not False):
extend = cmap.colorbar_extend
elif hasattr(norm, 'extend'):
extend = norm.extend
if (not isinstance(self.mappable, contour.ContourSet)
and getattr(self.cmap, 'colorbar_extend', False) is not False):
extend =self.cmap.colorbar_extend
elif hasattr(self.norm, 'extend'):
extend =self.norm.extend
else:
extend = 'neither'
self.alpha = None
# Call set_alpha to handle array-like alphas properly
self.set_alpha(alpha)
self.cmap = cmap
self.norm = norm
self.values = values
self.boundaries = boundaries
self.extend = extend
Expand DownExpand Up@@ -402,8 +407,8 @@
self._formatter = format # Assume it is a Formatter or None
self._draw_all()

if isinstance(mappable, contour.ContourSet) and not mappable.filled:
self.add_lines(mappable)
if isinstance(self.mappable, contour.ContourSet) and notself.mappable.filled:
self.add_lines(self.mappable)

# Link the Axes and Colorbar for interactive use
self.ax._colorbar = self
Expand All@@ -425,6 +430,31 @@
self._extend_cid2 = self.ax.callbacks.connect(
"ylim_changed", self._do_extends)

@property
def mappable(self):
return self._mappable

@property
def colorizer(self):
return self._colorizer

@colorizer.setter
def colorizer(self, colorizer):
self._colorizer = colorizer

Check warning on line 443 in lib/matplotlib/colorbar.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/colorbar.py#L443

Added line #L443 was not covered by tests
# need to know the norm as it is now
# so that we can monitor for changes in update_normal()
self._historic_norm = colorizer.norm

Check warning on line 446 in lib/matplotlib/colorbar.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/colorbar.py#L446

Added line #L446 was not covered by tests
# assume the norm is changed
self.update_normal()

Check warning on line 448 in lib/matplotlib/colorbar.py

View check run for this annotation

Codecov/ codecov/patch

lib/matplotlib/colorbar.py#L448

Added line #L448 was not covered by tests

@property
def cmap(self):
return self._colorizer.cmap

@property
def norm(self):
return self._colorizer.norm

@property
def long_axis(self):
"""Axis that has decorations (ticks, etc) on it."""
Expand DownExpand Up@@ -484,7 +514,7 @@
"""
Update solid patches, lines, etc.

This is meant to be called when the norm of the imageor contour plot
This is meant to be called when the norm of thecolorizer (imageetc.)
to which this colorbar belongs changes.

If the norm on the mappable is different than before, this resets the
Expand All@@ -503,12 +533,16 @@
# Therefore, the mappable keyword can be deprecated if cm.ScalarMappable
# is removed.
self.mappable = mappable
_log.debug('colorbar update normal %r %r', self.mappable.norm, self.norm)
self.set_alpha(self.mappable.get_alpha())
self.cmap = self.mappable.cmap
if self.mappable.norm != self.norm:
self.norm = self.mappable.norm

_log.debug('colorbar update normal %r %r',
self.colorizer.norm,
self._historic_norm)
if self.mappable:
self.set_alpha(self.mappable.get_alpha())

if self.colorizer.norm != self._historic_norm:
self._reset_locator_formatter_scale()
self._historic_norm = self.colorizer.norm

self._draw_all()
if isinstance(self.mappable, contour.ContourSet):
Expand DownExpand Up@@ -1032,9 +1066,9 @@

self.ax.remove()

self.mappable.callbacks.disconnect(self.mappable.colorbar_cid)
self.mappable.colorbar = None
self.mappable.colorbar_cid = None
self.colorizer.callbacks.disconnect(self.colorizer.colorbar_cid)
self.colorizer.colorbar = None
self.colorizer.colorbar_cid = None
# Remove the extension callbacks
self.ax.callbacks.disconnect(self._extend_cid1)
self.ax.callbacks.disconnect(self._extend_cid2)
Expand DownExpand Up@@ -1090,8 +1124,9 @@
b = np.hstack((b, b[-1] + 1))

# transform from 0-1 to vmin-vmax:
if self.mappable.get_array() is not None:
self.mappable.autoscale_None()
if self.mappable:
if self.mappable.get_array() is not None:
self.mappable.autoscale_None()
if not self.norm.scaled():
# If we still aren't scaled after autoscaling, use 0, 1 as default
self.norm.vmin = 0
Expand Down
15 changes: 11 additions & 4 deletionslib/matplotlib/colorbar.pyi
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,11 +22,8 @@ class _ColorbarSpine(mspines.Spines):

class Colorbar:
n_rasterize: int
mappable: cm.ScalarMappable | colorizer.ColorizingArtist
ax: Axes
alpha: float | None
cmap: colors.Colormap
norm: colors.Normalize
values: Sequence[float] | None
boundaries: Sequence[float] | None
extend: Literal["neither", "both", "min", "max"]
Expand All@@ -44,7 +41,7 @@ class Colorbar:
def __init__(
self,
ax: Axes,
mappable: cm.ScalarMappable | colorizer.ColorizingArtist | None = ...,
mappable: cm.ScalarMappable | colorizer.ColorizingArtist |colorizer.Colorizer |None = ...,
*,
cmap: str | colors.Colormap | None = ...,
norm: colors.Normalize | None = ...,
Expand All@@ -64,6 +61,16 @@ class Colorbar:
location: Literal["left", "right", "top", "bottom"] | None = ...
) -> None: ...
@property
def mappable(self) -> cm.ScalarMappable | colorizer.ColorizingArtist : ...
@property
def colorizer(self) -> colorizer.Colorizer : ...
@colorizer.setter
def colorizer(self, colorizer) -> None : ...
@property
def cmap(self) -> colors.Colormap : ...
@property
def norm(self) -> colors.Normalize : ...
@property
def long_axis(self) -> Axis: ...
@property
def locator(self) -> Locator: ...
Expand Down
18 changes: 9 additions & 9 deletionslib/matplotlib/figure.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1200,17 +1200,17 @@ def colorbar(
Parameters
----------
mappable
The `matplotlib.cm.ScalarMappable` (i.e., `.AxesImage`,
`.ContourSet`, etc.)described by this colorbar. This argument is
mandatory for the `.Figure.colorbar` method but optional for the
`.pyplot.colorbar`function, which sets the default tothecurrent
image.

Note that one can create a `.ScalarMappable` "on-the-fly" to
generate colorbars not attachedto a previously drawn artist, e.g.
The `matplotlib.colorizer.ColorizingArtist` (i.e., `.AxesImage`,
`.ContourSet`, etc.)or `matplotlib.colorizer.Colorizer` described
by thiscolorbar. This argument is mandatory for the
`.Figure.colorbar`method but optional forthe`.pyplot.colorbar`
function, which sets the default to the currentimage.

Note that one can create a `.Colorizer` "on-the-fly" to
generate colorbars not attachedan artist, e.g.
::

fig.colorbar(cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax)
fig.colorbar(colorizer.Colorizer(norm=norm, cmap=cmap), ax=ax)

cax : `~matplotlib.axes.Axes`, optional
Axes into which the colorbar will be drawn. If `None`, then a new
Expand Down
2 changes: 1 addition & 1 deletionlib/matplotlib/figure.pyi
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -169,7 +169,7 @@ class FigureBase(Artist):
) -> Text: ...
def colorbar(
self,
mappable: ScalarMappable | ColorizingArtist,
mappable: ScalarMappable | ColorizingArtist | Colorizer,
cax: Axes | None = ...,
ax: Axes | Iterable[Axes] | None = ...,
use_gridspec: bool = ...,
Expand Down
10 changes: 10 additions & 0 deletionslib/matplotlib/tests/test_colorbar.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1239,3 +1239,13 @@ def test_colorbar_format_string_and_old():
plt.imshow([[0, 1]])
cb = plt.colorbar(format="{x}%")
assert isinstance(cb._formatter, StrMethodFormatter)


def test_colorizer():
fig, ax = plt.subplots()
c = mpl.colorizer.Colorizer(norm=mcolors.Normalize(), cmap='viridis')
fig.colorbar(c, cax=ax)
c.vmin = -1
c.vmax = 2
np.testing.assert_almost_equal(ax.yaxis.get_ticklocs()[0], -1)
np.testing.assert_almost_equal(ax.yaxis.get_ticklocs()[-1], 2)
Loading

[8]ページ先頭

©2009-2025 Movatter.jp