|
55 | 55 | frommatplotlibimportrcParams
|
56 | 56 | frommatplotlibimportis_interactive
|
57 | 57 | frommatplotlibimportget_backend
|
58 |
| -frommatplotlib._pylab_helpersimportGcf |
59 | 58 | frommatplotlibimportlines
|
| 59 | +frommatplotlib._pylab_helpersimportGcf |
60 | 60 |
|
61 | 61 | frommatplotlib.transformsimportBbox,TransformedBbox,Affine2D
|
62 | 62 |
|
@@ -141,60 +141,118 @@ def get_registered_canvas_class(format):
|
141 | 141 | returnbackend_class
|
142 | 142 |
|
143 | 143 |
|
144 |
| -classShowBase(object): |
145 |
| -""" |
146 |
| - Simple base class to generate a show() callable in backends. |
| 144 | +class_Backend(object): |
| 145 | +# A backend can be defined by using the following pattern: |
| 146 | +# |
| 147 | +# @_Backend.export |
| 148 | +# class FooBackend(_Backend): |
| 149 | +# # override the attributes and methods documented below. |
147 | 150 |
|
148 |
| - Subclass must override mainloop() method. |
149 |
| - """ |
150 |
| -def__call__(self,block=None): |
| 151 | +# The following attributes and methods must be overridden by subclasses. |
| 152 | + |
| 153 | +# The `FigureCanvas` and `FigureManager` classes must be defined. |
| 154 | +FigureCanvas=None |
| 155 | +FigureManager=None |
| 156 | + |
| 157 | +# The following methods must be left as None for non-interactive backends. |
| 158 | +# For interactive backends, `trigger_manager_draw` should be a function |
| 159 | +# taking a manager as argument and triggering a canvas draw, and `mainloop` |
| 160 | +# should be a function taking no argument and starting the backend main |
| 161 | +# loop. |
| 162 | +trigger_manager_draw=None |
| 163 | +mainloop=None |
| 164 | + |
| 165 | +# The following methods will be automatically defined and exported, but |
| 166 | +# can be overridden. |
| 167 | + |
| 168 | +@classmethod |
| 169 | +defnew_figure_manager(cls,num,*args,**kwargs): |
| 170 | +"""Create a new figure manager instance. |
| 171 | + """ |
| 172 | +# This import needs to happen here due to circular imports. |
| 173 | +frommatplotlib.figureimportFigure |
| 174 | +fig_cls=kwargs.pop('FigureClass',Figure) |
| 175 | +fig=fig_cls(*args,**kwargs) |
| 176 | +returncls.new_figure_manager_given_figure(num,fig) |
| 177 | + |
| 178 | +@classmethod |
| 179 | +defnew_figure_manager_given_figure(cls,num,figure): |
| 180 | +"""Create a new figure manager instance for the given figure. |
151 | 181 | """
|
152 |
| - Show all figures. If *block* is not None, then |
153 |
| - it is a boolean that overrides all other factors |
154 |
| - determining whether show blocks by calling mainloop(). |
155 |
| - The other factors are: |
156 |
| - it does not block if run inside ipython's "%pylab" mode |
157 |
| - it does not block in interactive mode. |
| 182 | +canvas=cls.FigureCanvas(figure) |
| 183 | +manager=cls.FigureManager(canvas,num) |
| 184 | +returnmanager |
| 185 | + |
| 186 | +@classmethod |
| 187 | +defdraw_if_interactive(cls): |
| 188 | +ifcls.trigger_manager_drawisnotNoneandis_interactive(): |
| 189 | +manager=Gcf.get_active() |
| 190 | +ifmanager: |
| 191 | +cls.trigger_manager_draw(manager) |
| 192 | + |
| 193 | +@classmethod |
| 194 | +defshow(cls,block=None): |
| 195 | +"""Show all figures. |
| 196 | +
|
| 197 | + `show` blocks by calling `mainloop` if *block* is ``True``, or if it |
| 198 | + is ``None`` and we are neither in IPython's ``%pylab`` mode, nor in |
| 199 | + `interactive` mode. |
158 | 200 | """
|
| 201 | +ifcls.mainloopisNone: |
| 202 | +return |
159 | 203 | managers=Gcf.get_all_fig_managers()
|
160 | 204 | ifnotmanagers:
|
161 | 205 | return
|
162 |
| - |
163 | 206 | formanagerinmanagers:
|
164 | 207 | manager.show()
|
| 208 | +ifblockisNone: |
| 209 | +# Hack: Are we in IPython's pylab mode? |
| 210 | +frommatplotlibimportpyplot |
| 211 | +try: |
| 212 | +# IPython versions >= 0.10 tack the _needmain attribute onto |
| 213 | +# pyplot.show, and always set it to False, when in %pylab mode. |
| 214 | +ipython_pylab=notpyplot.show._needmain |
| 215 | +exceptAttributeError: |
| 216 | +ipython_pylab=False |
| 217 | +block=notipython_pylabandnotis_interactive() |
| 218 | +# TODO: The above is a hack to get the WebAgg backend working with |
| 219 | +# ipython's `%pylab` mode until proper integration is implemented. |
| 220 | +ifget_backend()=="WebAgg": |
| 221 | +block=True |
| 222 | +ifblock: |
| 223 | +cls.mainloop() |
| 224 | + |
| 225 | +# This method is the one actually exporting the required methods. |
| 226 | + |
| 227 | +@staticmethod |
| 228 | +defexport(cls): |
| 229 | +fornamein ["FigureCanvas", |
| 230 | +"FigureManager", |
| 231 | +"new_figure_manager", |
| 232 | +"new_figure_manager_given_figure", |
| 233 | +"draw_if_interactive", |
| 234 | +"show"]: |
| 235 | +setattr(sys.modules[cls.__module__],name,getattr(cls,name)) |
| 236 | + |
| 237 | +# For back-compatibility, generate a shim `Show` class. |
| 238 | + |
| 239 | +classShow(ShowBase): |
| 240 | +defmainloop(self): |
| 241 | +returncls.mainloop() |
| 242 | + |
| 243 | +setattr(sys.modules[cls.__module__],"Show",Show) |
| 244 | +returncls |
| 245 | + |
| 246 | + |
| 247 | +classShowBase(_Backend): |
| 248 | +""" |
| 249 | + Simple base class to generate a show() callable in backends. |
165 | 250 |
|
166 |
| -ifblockisnotNone: |
167 |
| -ifblock: |
168 |
| -self.mainloop() |
169 |
| -return |
170 |
| -else: |
171 |
| -return |
172 |
| - |
173 |
| -# Hack: determine at runtime whether we are |
174 |
| -# inside ipython in pylab mode. |
175 |
| -frommatplotlibimportpyplot |
176 |
| -try: |
177 |
| -ipython_pylab=notpyplot.show._needmain |
178 |
| -# IPython versions >= 0.10 tack the _needmain |
179 |
| -# attribute onto pyplot.show, and always set |
180 |
| -# it to False, when in %pylab mode. |
181 |
| -ipython_pylab=ipython_pylabandget_backend()!='WebAgg' |
182 |
| -# TODO: The above is a hack to get the WebAgg backend |
183 |
| -# working with ipython's `%pylab` mode until proper |
184 |
| -# integration is implemented. |
185 |
| -exceptAttributeError: |
186 |
| -ipython_pylab=False |
187 |
| - |
188 |
| -# Leave the following as a separate step in case we |
189 |
| -# want to control this behavior with an rcParam. |
190 |
| -ifipython_pylab: |
191 |
| -return |
192 |
| - |
193 |
| -ifnotis_interactive()orget_backend()=='WebAgg': |
194 |
| -self.mainloop() |
| 251 | + Subclass must override mainloop() method. |
| 252 | + """ |
195 | 253 |
|
196 |
| -defmainloop(self): |
197 |
| -pass |
| 254 | +def__call__(self,block=None): |
| 255 | +returnself.show(block=block) |
198 | 256 |
|
199 | 257 |
|
200 | 258 | classRendererBase(object):
|
|