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

Commit889c73f

Browse files
authored
Merge pull request#17605 from tacaswell/auto-backport-of-pr-17560-on-v3.2.x
Backport PR#17560: FIX: do not let no-op monkey patches to renderer …
2 parents29145cf +5a91618 commit889c73f

File tree

3 files changed

+61
-20
lines changed

3 files changed

+61
-20
lines changed

‎lib/matplotlib/backend_bases.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
The base class for the messaging area.
3333
"""
3434

35-
fromcontextlibimportcontextmanager
35+
fromcontextlibimportcontextmanager,suppress
3636
fromenumimportIntEnum
3737
importfunctools
3838
importimportlib
@@ -52,6 +52,7 @@
5252
frommatplotlib._pylab_helpersimportGcf
5353
frommatplotlib.transformsimportAffine2D
5454
frommatplotlib.pathimportPath
55+
frommatplotlib.cbookimport_setattr_cm
5556

5657
try:
5758
fromPILimport__version__asPILLOW_VERSION
@@ -712,6 +713,23 @@ def stop_filter(self, filter_func):
712713
Currently only supported by the agg renderer.
713714
"""
714715

716+
def_draw_disabled(self):
717+
"""
718+
Context manager to temporary disable drawing.
719+
720+
This is used for getting the drawn size of Artists. This lets us
721+
run the draw process to update any Python state but does not pay the
722+
cost of the draw_XYZ calls on the canvas.
723+
"""
724+
no_ops= {
725+
meth_name:lambda*args,**kwargs:None
726+
formeth_nameindir(RendererBase)
727+
if (meth_name.startswith("draw_")
728+
ormeth_namein ["open_group","close_group"])
729+
}
730+
731+
return_setattr_cm(self,**no_ops)
732+
715733

716734
classGraphicsContextBase:
717735
"""An abstract base class that provides color, line styles, etc."""
@@ -1520,15 +1538,14 @@ def __init__(self, name, canvas, key, x=0, y=0, guiEvent=None):
15201538
LocationEvent.__init__(self,name,canvas,x,y,guiEvent=guiEvent)
15211539

15221540

1523-
def_get_renderer(figure,print_method,*,draw_disabled=False):
1541+
def_get_renderer(figure,print_method):
15241542
"""
15251543
Get the renderer that would be used to save a `~.Figure`, and cache it on
15261544
the figure.
15271545
1528-
If *draw_disabled* is True, additionally replace drawing methods on
1529-
*renderer* by no-ops. This is used by the tight-bbox-saving renderer,
1530-
which needs to walk through the artist tree to compute the tight-bbox, but
1531-
for which the output file may be closed early.
1546+
If you need a renderer without any active draw methods use
1547+
renderer._draw_disabled to temporary patch them out at your call site.
1548+
15321549
"""
15331550
# This is implemented by triggering a draw, then immediately jumping out of
15341551
# Figure.draw() by raising an exception.
@@ -1544,12 +1561,6 @@ def _draw(renderer): raise Done(renderer)
15441561
exceptDoneasexc:
15451562
renderer,=figure._cachedRenderer,=exc.args
15461563

1547-
ifdraw_disabled:
1548-
formeth_nameindir(RendererBase):
1549-
if (meth_name.startswith("draw_")
1550-
ormeth_namein ["open_group","close_group"]):
1551-
setattr(renderer,meth_name,lambda*args,**kwargs:None)
1552-
15531564
returnrenderer
15541565

15551566

@@ -2079,9 +2090,13 @@ def print_figure(self, filename, dpi=None, facecolor=None, edgecolor=None,
20792090
renderer=_get_renderer(
20802091
self.figure,
20812092
functools.partial(
2082-
print_method,dpi=dpi,orientation=orientation),
2083-
draw_disabled=True)
2084-
self.figure.draw(renderer)
2093+
print_method,dpi=dpi,orientation=orientation)
2094+
)
2095+
ctx= (renderer._draw_disabled()
2096+
ifhasattr(renderer,'_draw_disabled')
2097+
elsesuppress())
2098+
withctx:
2099+
self.figure.draw(renderer)
20852100
bbox_artists=kwargs.pop("bbox_extra_artists",None)
20862101
bbox_inches=self.figure.get_tightbbox(renderer,
20872102
bbox_extra_artists=bbox_artists)

‎lib/matplotlib/figure.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2478,7 +2478,7 @@ def tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None,
24782478

24792479
from .tight_layoutimport (
24802480
get_renderer,get_subplotspec_list,get_tight_layout_figure)
2481-
2481+
fromcontextlibimportsuppress
24822482
subplotspec_list=get_subplotspec_list(self.axes)
24832483
ifNoneinsubplotspec_list:
24842484
cbook._warn_external("This figure includes Axes that are not "
@@ -2487,10 +2487,13 @@ def tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None,
24872487

24882488
ifrendererisNone:
24892489
renderer=get_renderer(self)
2490-
2491-
kwargs=get_tight_layout_figure(
2492-
self,self.axes,subplotspec_list,renderer,
2493-
pad=pad,h_pad=h_pad,w_pad=w_pad,rect=rect)
2490+
ctx= (renderer._draw_disabled()
2491+
ifhasattr(renderer,'_draw_disabled')
2492+
elsesuppress())
2493+
withctx:
2494+
kwargs=get_tight_layout_figure(
2495+
self,self.axes,subplotspec_list,renderer,
2496+
pad=pad,h_pad=h_pad,w_pad=w_pad,rect=rect)
24942497
ifkwargs:
24952498
self.subplots_adjust(**kwargs)
24962499

‎lib/matplotlib/tests/test_bbox_tight.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,26 @@ def test_tight_pcolorfast():
108108
# Previously, the bbox would include the area of the image clipped out by
109109
# the axes, resulting in a very tall image given the y limits of (0, 0.1).
110110
assertwidth>height
111+
112+
113+
deftest_noop_tight_bbox():
114+
fromPILimportImage
115+
x_size,y_size= (10,7)
116+
dpi=100
117+
# make the figure just the right size up front
118+
fig=plt.figure(frameon=False,dpi=dpi,figsize=(x_size/dpi,y_size/dpi))
119+
ax=plt.Axes(fig, [0.,0.,1.,1.])
120+
fig.add_axes(ax)
121+
ax.set_axis_off()
122+
ax.get_xaxis().set_visible(False)
123+
ax.get_yaxis().set_visible(False)
124+
125+
data=np.arange(x_size*y_size).reshape(y_size,x_size)
126+
ax.imshow(data)
127+
out=BytesIO()
128+
fig.savefig(out,bbox_inches='tight',pad_inches=0)
129+
out.seek(0)
130+
im=np.asarray(Image.open(out))
131+
assert (im[:, :,3]==255).all()
132+
assertnot (im[:, :, :3]==255).all()
133+
assertim.shape== (7,10,4)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp