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

Commitaaf140e

Browse files
authored
Merge pull request#15504 from anntzer/new_figure_in_main_thread
Warn when trying to start a GUI event loop out of the main thread.
2 parentse10e87c +ad90166 commitaaf140e

File tree

1 file changed

+50
-18
lines changed

1 file changed

+50
-18
lines changed

‎lib/matplotlib/pyplot.py

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
importre
2727
importsys
2828
importtime
29+
try:
30+
importthreading
31+
exceptImportError:
32+
importdummy_threadingasthreading
2933

3034
fromcyclerimportcycler
3135
importmatplotlib
@@ -175,6 +179,11 @@ def findobj(o=None, match=None, include_self=True):
175179
returno.findobj(match,include_self=include_self)
176180

177181

182+
def_get_required_interactive_framework(backend_mod):
183+
returngetattr(
184+
backend_mod.FigureCanvas,"required_interactive_framework",None)
185+
186+
178187
defswitch_backend(newbackend):
179188
"""
180189
Close all open figures and set the Matplotlib backend.
@@ -188,6 +197,8 @@ def switch_backend(newbackend):
188197
newbackend : str
189198
The name of the backend to use.
190199
"""
200+
global_backend_mod
201+
191202
close("all")
192203

193204
ifnewbackendisrcsetup._auto_backend_sentinel:
@@ -210,15 +221,17 @@ def switch_backend(newbackend):
210221
rcParamsOrig["backend"]="agg"
211222
return
212223

224+
# Backends are implemented as modules, but "inherit" default method
225+
# implementations from backend_bases._Backend. This is achieved by
226+
# creating a "class" that inherits from backend_bases._Backend and whose
227+
# body is filled with the module's globals.
228+
213229
backend_name=cbook._backend_module_name(newbackend)
214-
backend_mod=importlib.import_module(backend_name)
215-
Backend=type(
216-
"Backend", (matplotlib.backend_bases._Backend,),vars(backend_mod))
217-
_log.debug("Loaded backend %s version %s.",
218-
newbackend,Backend.backend_version)
219230

220-
required_framework=getattr(
221-
Backend.FigureCanvas,"required_interactive_framework",None)
231+
classbackend_mod(matplotlib.backend_bases._Backend):
232+
locals().update(vars(importlib.import_module(backend_name)))
233+
234+
required_framework=_get_required_interactive_framework(backend_mod)
222235
ifrequired_frameworkisnotNone:
223236
current_framework=cbook._get_running_interactive_framework()
224237
if (current_frameworkandrequired_framework
@@ -228,23 +241,42 @@ def switch_backend(newbackend):
228241
"framework, as {!r} is currently running".format(
229242
newbackend,required_framework,current_framework))
230243

231-
# Update both rcParams and rcDefaults so restoring the defaults later with
232-
# rcdefaults won't change the backend. A bit of overkill as 'backend' is
233-
# already in style.core.STYLE_BLACKLIST, but better to be safe.
234-
rcParams['backend']=rcParamsDefault['backend']=newbackend
244+
_log.debug("Loaded backend %s version %s.",
245+
newbackend,backend_mod.backend_version)
235246

236-
global_backend_mod,new_figure_manager,draw_if_interactive,_show
247+
rcParams['backend']=rcParamsDefault['backend']=newbackend
237248
_backend_mod=backend_mod
238-
new_figure_manager=Backend.new_figure_manager
239-
draw_if_interactive=Backend.draw_if_interactive
240-
_show=Backend.show
249+
forfunc_namein ["new_figure_manager","draw_if_interactive","show"]:
250+
globals()[func_name].__signature__=inspect.signature(
251+
getattr(backend_mod,func_name))
241252

242253
# Need to keep a global reference to the backend for compatibility reasons.
243254
# See https://github.com/matplotlib/matplotlib/issues/6092
244255
matplotlib.backends.backend=newbackend
245256

246257

247-
defshow(*args,**kw):
258+
def_warn_if_gui_out_of_main_thread():
259+
if (_get_required_interactive_framework(_backend_mod)
260+
andthreading.current_thread()isnotthreading.main_thread()):
261+
cbook._warn_external(
262+
"Starting a Matplotlib GUI outside of the main thread will likely "
263+
"fail.")
264+
265+
266+
# This function's signature is rewritten upon backend-load by switch_backend.
267+
defnew_figure_manager(*args,**kwargs):
268+
"""Create a new figure manager instance."""
269+
_warn_if_gui_out_of_main_thread()
270+
return_backend_mod.new_figure_manager(*args,**kwargs)
271+
272+
273+
# This function's signature is rewritten upon backend-load by switch_backend.
274+
defdraw_if_interactive(*args,**kwargs):
275+
return_backend_mod.draw_if_interactive(*args,**kwargs)
276+
277+
278+
# This function's signature is rewritten upon backend-load by switch_backend.
279+
defshow(*args,**kwargs):
248280
"""
249281
Display all figures.
250282
@@ -263,8 +295,8 @@ def show(*args, **kw):
263295
This is experimental, and may be set to ``True`` or ``False`` to
264296
override the blocking behavior described above.
265297
"""
266-
global_show
267-
return_show(*args,**kw)
298+
_warn_if_gui_out_of_main_thread()
299+
return_backend_mod.show(*args,**kwargs)
268300

269301

270302
defisinteractive():

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp