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

Commit617c5d6

Browse files
committed
Revival of the backend loading refactor.
1 parent40327be commit617c5d6

File tree

6 files changed

+154
-176
lines changed

6 files changed

+154
-176
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Non-interactive FigureManager classes are now aliases of FigureManagerBase
2+
``````````````````````````````````````````````````````````````````````````
3+
4+
The `FigureManagerPdf`, `FigureManagerPS`, and `FigureManagerSVG` classes,
5+
which were previously empty subclasses of `FigureManagerBase` (i.e., not
6+
adding or overriding any attribute or method), are now direct aliases for
7+
`FigureManagerBase`.

‎lib/matplotlib/backend_bases.py

Lines changed: 119 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -124,121 +124,6 @@ def get_registered_canvas_class(format):
124124
returnbackend_class
125125

126126

127-
class_Backend(object):
128-
# A backend can be defined by using the following pattern:
129-
#
130-
# @_Backend.export
131-
# class FooBackend(_Backend):
132-
# # override the attributes and methods documented below.
133-
134-
# The following attributes and methods must be overridden by subclasses.
135-
136-
# The `FigureCanvas` and `FigureManager` classes must be defined.
137-
FigureCanvas=None
138-
FigureManager=None
139-
140-
# The following methods must be left as None for non-interactive backends.
141-
# For interactive backends, `trigger_manager_draw` should be a function
142-
# taking a manager as argument and triggering a canvas draw, and `mainloop`
143-
# should be a function taking no argument and starting the backend main
144-
# loop.
145-
trigger_manager_draw=None
146-
mainloop=None
147-
148-
# The following methods will be automatically defined and exported, but
149-
# can be overridden.
150-
151-
@classmethod
152-
defnew_figure_manager(cls,num,*args,**kwargs):
153-
"""Create a new figure manager instance.
154-
"""
155-
# This import needs to happen here due to circular imports.
156-
frommatplotlib.figureimportFigure
157-
fig_cls=kwargs.pop('FigureClass',Figure)
158-
fig=fig_cls(*args,**kwargs)
159-
returncls.new_figure_manager_given_figure(num,fig)
160-
161-
@classmethod
162-
defnew_figure_manager_given_figure(cls,num,figure):
163-
"""Create a new figure manager instance for the given figure.
164-
"""
165-
canvas=cls.FigureCanvas(figure)
166-
manager=cls.FigureManager(canvas,num)
167-
returnmanager
168-
169-
@classmethod
170-
defdraw_if_interactive(cls):
171-
ifcls.trigger_manager_drawisnotNoneandis_interactive():
172-
manager=Gcf.get_active()
173-
ifmanager:
174-
cls.trigger_manager_draw(manager)
175-
176-
@classmethod
177-
defshow(cls,block=None):
178-
"""Show all figures.
179-
180-
`show` blocks by calling `mainloop` if *block* is ``True``, or if it
181-
is ``None`` and we are neither in IPython's ``%pylab`` mode, nor in
182-
`interactive` mode.
183-
"""
184-
managers=Gcf.get_all_fig_managers()
185-
ifnotmanagers:
186-
return
187-
formanagerinmanagers:
188-
# Emits a warning if the backend is non-interactive.
189-
manager.canvas.figure.show()
190-
ifcls.mainloopisNone:
191-
return
192-
ifblockisNone:
193-
# Hack: Are we in IPython's pylab mode?
194-
frommatplotlibimportpyplot
195-
try:
196-
# IPython versions >= 0.10 tack the _needmain attribute onto
197-
# pyplot.show, and always set it to False, when in %pylab mode.
198-
ipython_pylab=notpyplot.show._needmain
199-
exceptAttributeError:
200-
ipython_pylab=False
201-
block=notipython_pylabandnotis_interactive()
202-
# TODO: The above is a hack to get the WebAgg backend working with
203-
# ipython's `%pylab` mode until proper integration is implemented.
204-
ifget_backend()=="WebAgg":
205-
block=True
206-
ifblock:
207-
cls.mainloop()
208-
209-
# This method is the one actually exporting the required methods.
210-
211-
@staticmethod
212-
defexport(cls):
213-
fornamein ["FigureCanvas",
214-
"FigureManager",
215-
"new_figure_manager",
216-
"new_figure_manager_given_figure",
217-
"draw_if_interactive",
218-
"show"]:
219-
setattr(sys.modules[cls.__module__],name,getattr(cls,name))
220-
221-
# For back-compatibility, generate a shim `Show` class.
222-
223-
classShow(ShowBase):
224-
defmainloop(self):
225-
returncls.mainloop()
226-
227-
setattr(sys.modules[cls.__module__],"Show",Show)
228-
returncls
229-
230-
231-
classShowBase(_Backend):
232-
"""
233-
Simple base class to generate a show() callable in backends.
234-
235-
Subclass must override mainloop() method.
236-
"""
237-
238-
def__call__(self,block=None):
239-
returnself.show(block=block)
240-
241-
242127
classRendererBase(object):
243128
"""An abstract base class to handle drawing/rendering operations.
244129
@@ -3328,3 +3213,122 @@ def set_message(self, s):
33283213
Message text
33293214
"""
33303215
pass
3216+
3217+
3218+
class_Backend(object):
3219+
# A backend can be defined by using the following pattern:
3220+
#
3221+
# @_Backend.export
3222+
# class FooBackend(_Backend):
3223+
# # override the attributes and methods documented below.
3224+
3225+
# `backend_version` may be overridden by the subclass.
3226+
backend_version="unknown"
3227+
3228+
# The `FigureCanvas` class must be defined.
3229+
FigureCanvas=None
3230+
3231+
# For interactive backends, the `FigureManager` class must be overridden.
3232+
FigureManager=FigureManagerBase
3233+
3234+
# The following methods must be left as None for non-interactive backends.
3235+
# For interactive backends, `trigger_manager_draw` should be a function
3236+
# taking a manager as argument and triggering a canvas draw, and `mainloop`
3237+
# should be a function taking no argument and starting the backend main
3238+
# loop.
3239+
trigger_manager_draw=None
3240+
mainloop=None
3241+
3242+
# The following methods will be automatically defined and exported, but
3243+
# can be overridden.
3244+
3245+
@classmethod
3246+
defnew_figure_manager(cls,num,*args,**kwargs):
3247+
"""Create a new figure manager instance.
3248+
"""
3249+
# This import needs to happen here due to circular imports.
3250+
frommatplotlib.figureimportFigure
3251+
fig_cls=kwargs.pop('FigureClass',Figure)
3252+
fig=fig_cls(*args,**kwargs)
3253+
returncls.new_figure_manager_given_figure(num,fig)
3254+
3255+
@classmethod
3256+
defnew_figure_manager_given_figure(cls,num,figure):
3257+
"""Create a new figure manager instance for the given figure.
3258+
"""
3259+
canvas=cls.FigureCanvas(figure)
3260+
manager=cls.FigureManager(canvas,num)
3261+
returnmanager
3262+
3263+
@classmethod
3264+
defdraw_if_interactive(cls):
3265+
ifcls.trigger_manager_drawisnotNoneandis_interactive():
3266+
manager=Gcf.get_active()
3267+
ifmanager:
3268+
cls.trigger_manager_draw(manager)
3269+
3270+
@classmethod
3271+
defshow(cls,block=None):
3272+
"""Show all figures.
3273+
3274+
`show` blocks by calling `mainloop` if *block* is ``True``, or if it
3275+
is ``None`` and we are neither in IPython's ``%pylab`` mode, nor in
3276+
`interactive` mode.
3277+
"""
3278+
managers=Gcf.get_all_fig_managers()
3279+
ifnotmanagers:
3280+
return
3281+
formanagerinmanagers:
3282+
# Emits a warning if the backend is non-interactive.
3283+
manager.canvas.figure.show()
3284+
ifcls.mainloopisNone:
3285+
return
3286+
ifblockisNone:
3287+
# Hack: Are we in IPython's pylab mode?
3288+
frommatplotlibimportpyplot
3289+
try:
3290+
# IPython versions >= 0.10 tack the _needmain attribute onto
3291+
# pyplot.show, and always set it to False, when in %pylab mode.
3292+
ipython_pylab=notpyplot.show._needmain
3293+
exceptAttributeError:
3294+
ipython_pylab=False
3295+
block=notipython_pylabandnotis_interactive()
3296+
# TODO: The above is a hack to get the WebAgg backend working with
3297+
# ipython's `%pylab` mode until proper integration is implemented.
3298+
ifget_backend()=="WebAgg":
3299+
block=True
3300+
ifblock:
3301+
cls.mainloop()
3302+
3303+
# This method is the one actually exporting the required methods.
3304+
3305+
@staticmethod
3306+
defexport(cls):
3307+
fornamein ["backend_version",
3308+
"FigureCanvas",
3309+
"FigureManager",
3310+
"new_figure_manager",
3311+
"new_figure_manager_given_figure",
3312+
"draw_if_interactive",
3313+
"show"]:
3314+
setattr(sys.modules[cls.__module__],name,getattr(cls,name))
3315+
3316+
# For back-compatibility, generate a shim `Show` class.
3317+
3318+
classShow(ShowBase):
3319+
defmainloop(self):
3320+
returncls.mainloop()
3321+
3322+
setattr(sys.modules[cls.__module__],"Show",Show)
3323+
returncls
3324+
3325+
3326+
classShowBase(_Backend):
3327+
"""
3328+
Simple base class to generate a show() callable in backends.
3329+
3330+
Subclass must override mainloop() method.
3331+
"""
3332+
3333+
def__call__(self,block=None):
3334+
returnself.show(block=block)

‎lib/matplotlib/backends/__init__.py

Lines changed: 24 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
importinspect
1+
importimportlib
22
importlogging
33
importtraceback
4-
importwarnings
54

65
importmatplotlib
6+
frommatplotlib.backend_basesimport_Backend
77

88
_log=logging.getLogger(__name__)
99

@@ -15,10 +15,11 @@
1515

1616

1717
defpylab_setup(name=None):
18-
'''return new_figure_manager, draw_if_interactive and show for pyplot
18+
"""
19+
Return new_figure_manager, draw_if_interactive and show for pyplot.
1920
20-
This provides the backend-specific functions that are used by
21-
pyplot toabstract away the difference between interactive backends.
21+
This provides the backend-specific functions that are used by pyplot to
22+
abstract away the difference between backends.
2223
2324
Parameters
2425
----------
@@ -39,54 +40,25 @@ def pylab_setup(name=None):
3940
4041
show : function
4142
Show (and possibly block) any unshown figures.
42-
43-
'''
44-
# Import the requested backend into a generic module object
43+
"""
44+
# Import the requested backend into a generic module object.
4545
ifnameisNone:
46-
# validates, to match all_backends
4746
name=matplotlib.get_backend()
48-
ifname.startswith('module://'):
49-
backend_name=name[9:]
50-
else:
51-
backend_name='backend_'+name
52-
backend_name=backend_name.lower()# until we banish mixed case
53-
backend_name='matplotlib.backends.%s'%backend_name.lower()
54-
55-
# the last argument is specifies whether to use absolute or relative
56-
# imports. 0 means only perform absolute imports.
57-
backend_mod=__import__(backend_name,globals(),locals(),
58-
[backend_name],0)
59-
60-
# Things we pull in from all backends
61-
new_figure_manager=backend_mod.new_figure_manager
62-
63-
# image backends like pdf, agg or svg do not need to do anything
64-
# for "show" or "draw_if_interactive", so if they are not defined
65-
# by the backend, just do nothing
66-
defdo_nothing_show(*args,**kwargs):
67-
frame=inspect.currentframe()
68-
fname=frame.f_back.f_code.co_filename
69-
iffnamein ('<stdin>','<ipython console>'):
70-
warnings.warn("""
71-
Your currently selected backend, '%s' does not support show().
72-
Please select a GUI backend in your matplotlibrc file ('%s')
73-
or with matplotlib.use()"""%
74-
(name,matplotlib.matplotlib_fname()),stacklevel=2)
75-
76-
defdo_nothing(*args,**kwargs):
77-
pass
78-
79-
backend_version=getattr(backend_mod,'backend_version','unknown')
80-
81-
show=getattr(backend_mod,'show',do_nothing_show)
82-
83-
draw_if_interactive=getattr(backend_mod,'draw_if_interactive',
84-
do_nothing)
85-
86-
_log.debug('backend %s version %s',name,backend_version)
87-
88-
# need to keep a global reference to the backend for compatibility
89-
# reasons. See https://github.com/matplotlib/matplotlib/issues/6092
47+
backend_name= (name[9:]ifname.startswith("module://")
48+
else"matplotlib.backends.backend_{}".format(name.lower()))
49+
backend_mod=importlib.import_module(backend_name)
50+
# Create a local Backend class whose body corresponds to the contents of
51+
# the backend module. This allows the Backend class to fill in the missing
52+
# methods through inheritance.
53+
Backend=type("Backend", (_Backend,),vars(backend_mod))
54+
55+
# Need to keep a global reference to the backend for compatibility reasons.
56+
# See https://github.com/matplotlib/matplotlib/issues/6092
9057
globalbackend
9158
backend=name
92-
returnbackend_mod,new_figure_manager,draw_if_interactive,show
59+
60+
_log.debug('backend %s version %s',name,Backend.backend_version)
61+
return (backend_mod,
62+
Backend.new_figure_manager,
63+
Backend.draw_if_interactive,
64+
Backend.show)

‎lib/matplotlib/backends/backend_pdf.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2575,11 +2575,9 @@ def print_pdf(self, filename, *,
25752575
file.close()
25762576

25772577

2578-
classFigureManagerPdf(FigureManagerBase):
2579-
pass
2578+
FigureManagerPdf=FigureManagerBase
25802579

25812580

25822581
@_Backend.export
25832582
class_BackendPdf(_Backend):
25842583
FigureCanvas=FigureCanvasPdf
2585-
FigureManager=FigureManagerPdf

‎lib/matplotlib/backends/backend_ps.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,8 +1695,7 @@ def pstoeps(tmpfile, bbox=None, rotated=False):
16951695
shutil.move(epsfile,tmpfile)
16961696

16971697

1698-
classFigureManagerPS(FigureManagerBase):
1699-
pass
1698+
FigureManagerPS=FigureManagerBase
17001699

17011700

17021701
# The following Python dictionary psDefs contains the entries for the
@@ -1742,4 +1741,3 @@ class FigureManagerPS(FigureManagerBase):
17421741
@_Backend.export
17431742
class_BackendPS(_Backend):
17441743
FigureCanvas=FigureCanvasPS
1745-
FigureManager=FigureManagerPS

‎lib/matplotlib/backends/backend_svg.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,8 +1213,8 @@ def _print_svg(
12131213
defget_default_filetype(self):
12141214
return'svg'
12151215

1216-
classFigureManagerSVG(FigureManagerBase):
1217-
pass
1216+
1217+
FigureManagerSVG=FigureManagerBase
12181218

12191219

12201220
svgProlog="""\
@@ -1228,4 +1228,3 @@ class FigureManagerSVG(FigureManagerBase):
12281228
@_Backend.export
12291229
class_BackendSVG(_Backend):
12301230
FigureCanvas=FigureCanvasSVG
1231-
FigureManager=FigureManagerSVG

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp