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

Force clipped-log when drawing log-histograms.#9305

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

Closed
Closed
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
32 changes: 32 additions & 0 deletionslib/matplotlib/artist.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,6 +4,7 @@
import six

from collections import OrderedDict, namedtuple
import contextlib
from functools import wraps
import inspect
import re
Expand DownExpand Up@@ -120,6 +121,22 @@ def __init__(self):
self._path_effects = rcParams['path.effects']
self._sticky_edges = _XYPair([], [])

# When plotting in log-scale, force the use of clip mode instead of
# mask. The typical (internal) use case is log-scaled bar plots and
# error bars. Ideally we'd want BarContainers / ErrorbarContainers
# to have their own show() method which takes care of the patching,
# but right now Containers are not taken into account during
# the draw; instead their components (in the case of bar plots,
# these are Rectangle patches; in the case of ErrorbarContainers,
# LineCollections) are drawn individually, so tracking the force_clip
# state must be done by the component artists. Note that handling of
# _force_clip_in_log_scale must be done by the individual artists'
# draw implementation; right now only Patches and Collections support
# it. The `_forcing_clip_in_log_scale` decorator may be helpful to
# implement such support, it should typically be applied around a call
# to `transform_path_non_affine`.
self._force_clip_in_log_scale = False

def __getstate__(self):
d = self.__dict__.copy()
# remove the unpicklable remove method, this will get re-added on load
Expand DownExpand Up@@ -779,6 +796,21 @@ def draw(self, renderer, *args, **kwargs):
return
self.stale = False

@contextlib.contextmanager
def _forcing_clip_in_log_scale(self):
# See _force_clip_in_log_scale for explanation.
fvs = {}
if self._force_clip_in_log_scale and self.axes:
for axis in self.axes._get_axis_list():
if axis.get_scale() == "log":
fvs[axis] = axis._scale._transform._fill_value
axis._scale._transform._fill_value = 1e-300
try:
yield
finally:
for axis, fv in fvs.items():
axis._scale._transform._fill_value = fv

def set_alpha(self, alpha):
"""
Set the alpha value used for blending - not supported on
Expand Down
11 changes: 9 additions & 2 deletionslib/matplotlib/axes/_axes.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2158,6 +2158,7 @@ def bar(self, *args, **kwargs):
r.sticky_edges.y.append(b)
elif orientation == 'horizontal':
r.sticky_edges.x.append(l)
r._force_clip_in_log_scale = True
self.add_patch(r)
patches.append(r)

Expand DownExpand Up@@ -3053,7 +3054,9 @@ def extract_err(err, data):
if xlolims.any():
yo, _ = xywhere(y, right, xlolims & everymask)
lo, ro = xywhere(x, right, xlolims & everymask)
barcols.append(self.hlines(yo, lo, ro, **eb_lines_style))
ebs = self.hlines(yo, lo, ro, **eb_lines_style)
ebs._force_clip_in_log_scale = True
barcols.append(ebs)
rightup, yup = xywhere(right, y, xlolims & everymask)
if self.xaxis_inverted():
marker = mlines.CARETLEFTBASE
Expand DownExpand Up@@ -3092,7 +3095,9 @@ def extract_err(err, data):
if noylims.any():
xo, _ = xywhere(x, lower, noylims & everymask)
lo, uo = xywhere(lower, upper, noylims & everymask)
barcols.append(self.vlines(xo, lo, uo, **eb_lines_style))
ebs = self.vlines(xo, lo, uo, **eb_lines_style)
ebs._force_clip_in_log_scale = True
barcols.append(ebs)
if capsize > 0:
caplines.append(mlines.Line2D(xo, lo, marker='_',
**eb_cap_style))
Expand DownExpand Up@@ -4905,6 +4910,7 @@ def get_interp_point(ind):
polys.append(X)

collection = mcoll.PolyCollection(polys, **kwargs)
collection._force_clip_in_log_scale = True

# now update the datalim and autoscale
XY1 = np.array([x[where], y1[where]]).T
Expand DownExpand Up@@ -5057,6 +5063,7 @@ def get_interp_point(ind):
polys.append(Y)

collection = mcoll.PolyCollection(polys, **kwargs)
collection._force_clip_in_log_scale = True

# now update the datalim and autoscale
X1Y = np.array([x1[where], y[where]]).T
Expand Down
5 changes: 3 additions & 2 deletionslib/matplotlib/collections.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -232,8 +232,9 @@ def _prepare_points(self):
offsets = np.column_stack([xs, ys])

if not transform.is_affine:
paths = [transform.transform_path_non_affine(path)
for path in paths]
with self._forcing_clip_in_log_scale():
paths = [transform.transform_path_non_affine(path)
for path in paths]
transform = transform.get_affine()
if not transOffset.is_affine:
offsets = transOffset.transform_non_affine(offsets)
Expand Down
5 changes: 4 additions & 1 deletionlib/matplotlib/patches.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -564,7 +564,10 @@ def draw(self, renderer):

path = self.get_path()
transform = self.get_transform()
tpath = transform.transform_path_non_affine(path)

with self._forcing_clip_in_log_scale():
tpath = transform.transform_path_non_affine(path)

affine = transform.get_affine()

if self.get_path_effects():
Expand Down
18 changes: 18 additions & 0 deletionslib/matplotlib/tests/test_axes.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5412,3 +5412,21 @@ def test_patch_deprecations():
assert fig.patch == fig.figurePatch

assert len(w) == 2


@pytest.mark.parametrize("plotter",
[lambda ax: ax.bar([0, 1], [1, 2]),
lambda ax: ax.errorbar([0, 1], [2, 2], [1, 3]),
lambda ax: ax.fill_between([0, 1], [1, 2], [1, 0])])
def test_clipped_log_zero(plotter):
fig, ax = plt.subplots()
plotter(ax)
ax.set_yscale("log")
png1 = io.BytesIO()
fig.savefig(png1, format="png")
fig, ax = plt.subplots()
plotter(ax)
ax.set_yscale("log", nonposy="clip")
png2 = io.BytesIO()
fig.savefig(png2, format="png")
assert png1.getvalue() == png2.getvalue()

[8]ページ先頭

©2009-2025 Movatter.jp