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

Commite7f01a4

Browse files
committed
FIX/API:fig.canvas.draw always updates internal state
Previously the non-interactive backends, other than Agg, did notdefine `draw` methods and fell back to the base no-op version.However, we have been documenting that the correct way to update thevarious internal state we keep (run tight/constrained layouts, autolimits, text size/position, ...), this is now a bug due to oursuggested usage drifting.closes#18407
1 parent5b835ee commite7f01a4

File tree

6 files changed

+60
-6
lines changed

6 files changed

+60
-6
lines changed

‎lib/matplotlib/backend_bases.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,6 +1587,12 @@ def _draw(renderer): raise Done(renderer)
15871587
figure.canvas=orig_canvas
15881588

15891589

1590+
def_no_op_draw(figure):
1591+
renderer=_get_renderer(figure)
1592+
withrenderer._draw_disabled():
1593+
figure.draw(renderer)
1594+
1595+
15901596
def_is_non_interactive_terminal_ipython(ip):
15911597
"""
15921598
Return whether we are in a a terminal IPython, but non interactive.
@@ -1624,7 +1630,7 @@ def _check_savefig_extra_args(func=None, extra_kwargs=()):
16241630
@functools.wraps(func)
16251631
defwrapper(*args,**kwargs):
16261632
name='savefig'# Reasonable default guess.
1627-
public_api=re.compile(r'^savefig|print_[A-Za-z0-9]+$')
1633+
public_api=re.compile(r'^savefig|print_[A-Za-z0-9]+|_no_op_draw$')
16281634
seen_print_figure=False
16291635
forframe,lineintraceback.walk_stack(None):
16301636
ifframeisNone:
@@ -1635,8 +1641,9 @@ def wrapper(*args, **kwargs):
16351641
frame.f_globals.get('__name__','')):
16361642
ifpublic_api.match(frame.f_code.co_name):
16371643
name=frame.f_code.co_name
1638-
ifname=='print_figure':
1644+
ifnamein ('print_figure','_no_op_draw'):
16391645
seen_print_figure=True
1646+
16401647
else:
16411648
break
16421649

‎lib/matplotlib/backends/backend_pdf.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
frommatplotlib._pylab_helpersimportGcf
2929
frommatplotlib.backend_basesimport (
3030
_Backend,_check_savefig_extra_args,FigureCanvasBase,FigureManagerBase,
31-
GraphicsContextBase,RendererBase)
31+
GraphicsContextBase,RendererBase,_no_op_draw)
3232
frommatplotlib.backends.backend_mixedimportMixedModeRenderer
3333
frommatplotlib.figureimportFigure
3434
frommatplotlib.font_managerimportfindfont,is_opentype_cff_font,get_font
@@ -2707,6 +2707,9 @@ def print_pdf(self, filename, *,
27072707
else:# we opened the file above; now finish it off
27082708
file.close()
27092709

2710+
defdraw(self,*args,**kwargs):
2711+
_no_op_draw(self.figure)
2712+
returnsuper().draw(*args,**kwargs)
27102713

27112714
FigureManagerPdf=FigureManagerBase
27122715

‎lib/matplotlib/backends/backend_pgf.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
frommatplotlibimportcbook,font_managerasfm
2020
frommatplotlib.backend_basesimport (
2121
_Backend,_check_savefig_extra_args,FigureCanvasBase,FigureManagerBase,
22-
GraphicsContextBase,RendererBase)
22+
GraphicsContextBase,RendererBase,_no_op_draw
23+
)
2324
frommatplotlib.backends.backend_mixedimportMixedModeRenderer
2425
frommatplotlib.backends.backend_pdfimport (
2526
_create_pdf_info_dict,_datetime_to_pdf)
@@ -970,6 +971,10 @@ def print_png(self, fname_or_fh, *args, **kwargs):
970971
defget_renderer(self):
971972
returnRendererPgf(self.figure,None)
972973

974+
defdraw(self,*args,**kwargs):
975+
_no_op_draw(self.figure)
976+
returnsuper().draw()
977+
973978

974979
FigureManagerPgf=FigureManagerBase
975980

‎lib/matplotlib/backends/backend_ps.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
frommatplotlib.afmimportAFM
2424
frommatplotlib.backend_basesimport (
2525
_Backend,_check_savefig_extra_args,FigureCanvasBase,FigureManagerBase,
26-
GraphicsContextBase,RendererBase)
26+
GraphicsContextBase,RendererBase,_no_op_draw)
2727
frommatplotlib.cbookimportis_writable_file_like,file_requires_unicode
2828
frommatplotlib.font_managerimportis_opentype_cff_font,get_font
2929
frommatplotlib.ft2fontimportLOAD_NO_HINTING
@@ -1111,6 +1111,9 @@ def write(self, *args, **kwargs):
11111111

11121112
_move_path_to_path_or_stream(tmpfile,outfile)
11131113

1114+
defdraw(self,*args,**kwargs):
1115+
_no_op_draw(self.figure)
1116+
returnsuper().draw()
11141117

11151118
defconvert_psfrags(tmpfile,psfrags,font_preamble,custom_preamble,
11161119
paper_width,paper_height,orientation):

‎lib/matplotlib/backends/backend_svg.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
frommatplotlibimportcbook
1818
frommatplotlib.backend_basesimport (
1919
_Backend,_check_savefig_extra_args,FigureCanvasBase,FigureManagerBase,
20-
RendererBase)
20+
RendererBase,_no_op_draw)
2121
frommatplotlib.backends.backend_mixedimportMixedModeRenderer
2222
frommatplotlib.colorsimportrgb2hex
2323
frommatplotlib.datesimportUTC
@@ -1360,6 +1360,9 @@ def _print_svg(self, filename, fh, *, dpi=72, bbox_inches_restore=None,
13601360
defget_default_filetype(self):
13611361
return'svg'
13621362

1363+
defdraw(self,*args,**kwargs):
1364+
_no_op_draw(self.figure)
1365+
returnsuper().draw()
13631366

13641367
FigureManagerSVG=FigureManagerBase
13651368

‎lib/matplotlib/tests/test_backend_bases.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,36 @@ def test_interactive_zoom():
157157

158158
tb.zoom()
159159
assertax.get_navigate_mode()isNone
160+
161+
162+
@pytest.mark.parametrize("backend", ['svg','pgf','ps','pdf'])
163+
deftest_draw(backend):
164+
frommatplotlib.figureimportFigure
165+
frommatplotlib.backends.backend_aggimportFigureCanvas
166+
test_backend=pytest.importorskip(
167+
f'matplotlib.backends.backend_{backend}'
168+
)
169+
TestCanvas=test_backend.FigureCanvas
170+
fig_test=Figure(constrained_layout=True)
171+
TestCanvas(fig_test)
172+
axes_test=fig_test.subplots(2,2)
173+
174+
# defaults to FigureCanvasBase
175+
fig_agg=Figure(constrained_layout=True)
176+
# put a backends.backend_agg.FigureCanvas on it
177+
FigureCanvas(fig_agg)
178+
axes_agg=fig_agg.subplots(2,2)
179+
180+
init_pos= [ax.get_position()foraxinaxes_test.ravel()]
181+
182+
fig_test.canvas.draw()
183+
fig_agg.canvas.draw()
184+
185+
layed_out_pos_test= [ax.get_position()foraxinaxes_test.ravel()]
186+
layed_out_pos_agg= [ax.get_position()foraxinaxes_agg.ravel()]
187+
188+
forinit,placedinzip(init_pos,layed_out_pos_test):
189+
assertnotnp.allclose(init,placed,atol=0.005)
190+
191+
forref,testinzip(layed_out_pos_agg,layed_out_pos_test):
192+
np.testing.assert_allclose(ref,test,atol=0.005)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp