| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c280700 commit 54e3169
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -41,13 +41,15 @@ | |||
| 41 | 41 | from contextlib import contextmanager | |
| 42 | 42 | from functools import partial | |
| 43 | 43 | import importlib | |
| 44 | + import inspect | ||
| 44 | 45 | import io | |
| 45 | 46 | import os | |
| 46 | 47 | import sys | |
| 47 | 48 | import time | |
| 48 | 49 | import warnings | |
| 49 | 50 | ||
| 50 | 51 | import numpy as np | |
| 52 | + import matplotlib | ||
| 51 | 53 | import matplotlib.cbook as cbook | |
| 52 | 54 | import matplotlib.colors as colors | |
| 53 | 55 | import matplotlib.transforms as transforms | |
@@ -135,120 +137,6 @@ def get_registered_canvas_class(format): | |||
| 135 | 137 | return backend_class | |
| 136 | 138 | ||
| 137 | 139 | ||
| 138 | - class _Backend(object): | ||
| 139 | - # A backend can be defined by using the following pattern: | ||
| 140 | - # | ||
| 141 | - # @_Backend.export | ||
| 142 | - # class FooBackend(_Backend): | ||
| 143 | - # # override the attributes and methods documented below. | ||
| 144 | - | ||
| 145 | - # The following attributes and methods must be overridden by subclasses. | ||
| 146 | - | ||
| 147 | - # The `FigureCanvas` and `FigureManager` classes must be defined. | ||
| 148 | - FigureCanvas = None | ||
| 149 | - FigureManager = None | ||
| 150 | - | ||
| 151 | - # The following methods must be left as None for non-interactive backends. | ||
| 152 | - # For interactive backends, `trigger_manager_draw` should be a function | ||
| 153 | - # taking a manager as argument and triggering a canvas draw, and `mainloop` | ||
| 154 | - # should be a function taking no argument and starting the backend main | ||
| 155 | - # loop. | ||
| 156 | - trigger_manager_draw = None | ||
| 157 | - mainloop = None | ||
| 158 | - | ||
| 159 | - # The following methods will be automatically defined and exported, but | ||
| 160 | - # can be overridden. | ||
| 161 | - | ||
| 162 | - @classmethod | ||
| 163 | - def new_figure_manager(cls, num, *args, **kwargs): | ||
| 164 | - """Create a new figure manager instance. | ||
| 165 | - """ | ||
| 166 | - # This import needs to happen here due to circular imports. | ||
| 167 | - from matplotlib.figure import Figure | ||
| 168 | - fig_cls = kwargs.pop('FigureClass', Figure) | ||
| 169 | - fig = fig_cls(*args, **kwargs) | ||
| 170 | - return cls.new_figure_manager_given_figure(num, fig) | ||
| 171 | - | ||
| 172 | - @classmethod | ||
| 173 | - def new_figure_manager_given_figure(cls, num, figure): | ||
| 174 | - """Create a new figure manager instance for the given figure. | ||
| 175 | - """ | ||
| 176 | - canvas = cls.FigureCanvas(figure) | ||
| 177 | - manager = cls.FigureManager(canvas, num) | ||
| 178 | - return manager | ||
| 179 | - | ||
| 180 | - @classmethod | ||
| 181 | - def draw_if_interactive(cls): | ||
| 182 | - if cls.trigger_manager_draw is not None and is_interactive(): | ||
| 183 | - manager = Gcf.get_active() | ||
| 184 | - if manager: | ||
| 185 | - cls.trigger_manager_draw(manager) | ||
| 186 | - | ||
| 187 | - @classmethod | ||
| 188 | - def show(cls, block=None): | ||
| 189 | - """Show all figures. | ||
| 190 | - | ||
| 191 | - `show` blocks by calling `mainloop` if *block* is ``True``, or if it | ||
| 192 | - is ``None`` and we are neither in IPython's ``%pylab`` mode, nor in | ||
| 193 | - `interactive` mode. | ||
| 194 | - """ | ||
| 195 | - if cls.mainloop is None: | ||
| 196 | - return | ||
| 197 | - managers = Gcf.get_all_fig_managers() | ||
| 198 | - if not managers: | ||
| 199 | - return | ||
| 200 | - for manager in managers: | ||
| 201 | - manager.show() | ||
| 202 | - if block is None: | ||
| 203 | - # Hack: Are we in IPython's pylab mode? | ||
| 204 | - from matplotlib import pyplot | ||
| 205 | - try: | ||
| 206 | - # IPython versions >= 0.10 tack the _needmain attribute onto | ||
| 207 | - # pyplot.show, and always set it to False, when in %pylab mode. | ||
| 208 | - ipython_pylab = not pyplot.show._needmain | ||
| 209 | - except AttributeError: | ||
| 210 | - ipython_pylab = False | ||
| 211 | - block = not ipython_pylab and not is_interactive() | ||
| 212 | - # TODO: The above is a hack to get the WebAgg backend working with | ||
| 213 | - # ipython's `%pylab` mode until proper integration is implemented. | ||
| 214 | - if get_backend() == "WebAgg": | ||
| 215 | - block = True | ||
| 216 | - if block: | ||
| 217 | - cls.mainloop() | ||
| 218 | - | ||
| 219 | - # This method is the one actually exporting the required methods. | ||
| 220 | - | ||
| 221 | - @staticmethod | ||
| 222 | - def export(cls): | ||
| 223 | - for name in ["FigureCanvas", | ||
| 224 | - "FigureManager", | ||
| 225 | - "new_figure_manager", | ||
| 226 | - "new_figure_manager_given_figure", | ||
| 227 | - "draw_if_interactive", | ||
| 228 | - "show"]: | ||
| 229 | - setattr(sys.modules[cls.__module__], name, getattr(cls, name)) | ||
| 230 | - | ||
| 231 | - # For back-compatibility, generate a shim `Show` class. | ||
| 232 | - | ||
| 233 | - class Show(ShowBase): | ||
| 234 | - def mainloop(self): | ||
| 235 | - return cls.mainloop() | ||
| 236 | - | ||
| 237 | - setattr(sys.modules[cls.__module__], "Show", Show) | ||
| 238 | - return cls | ||
| 239 | - | ||
| 240 | - | ||
| 241 | - class ShowBase(_Backend): | ||
| 242 | - """ | ||
| 243 | - Simple base class to generate a show() callable in backends. | ||
| 244 | - | ||
| 245 | - Subclass must override mainloop() method. | ||
| 246 | - """ | ||
| 247 | - | ||
| 248 | - def __call__(self, block=None): | ||
| 249 | - return self.show(block=block) | ||
| 250 | - | ||
| 251 | - | ||
| 252 | 140 | class RendererBase(object): | |
| 253 | 141 | """An abstract base class to handle drawing/rendering operations. | |
| 254 | 142 | ||
@@ -3367,3 +3255,129 @@ def set_message(self, s): | |||
| 3367 | 3255 | Message text | |
| 3368 | 3256 | """ | |
| 3369 | 3257 | pass | |
| 3258 | + | ||
| 3259 | + | ||
| 3260 | + class _Backend(object): | ||
| 3261 | + # A backend can be defined by using the following pattern: | ||
| 3262 | + # | ||
| 3263 | + # @_Backend.export | ||
| 3264 | + # class FooBackend(_Backend): | ||
| 3265 | + # # override the attributes and methods documented below. | ||
| 3266 | + | ||
| 3267 | + # May be overridden by the subclass. | ||
| 3268 | + backend_version = "unknown" | ||
| 3269 | + # The `FigureCanvas` class must be overridden. | ||
| 3270 | + FigureCanvas = None | ||
| 3271 | + # For interactive backends, the `FigureManager` class must be overridden. | ||
| 3272 | + FigureManager = FigureManagerBase | ||
| 3273 | + # The following methods must be left as None for non-interactive backends. | ||
| 3274 | + # For interactive backends, `trigger_manager_draw` should be a function | ||
| 3275 | + # taking a manager as argument and triggering a canvas draw, and `mainloop` | ||
| 3276 | + # should be a function taking no argument and starting the backend main | ||
| 3277 | + # loop. | ||
| 3278 | + trigger_manager_draw = None | ||
| 3279 | + mainloop = None | ||
| 3280 | + | ||
| 3281 | + # The following methods will be automatically defined and exported, but | ||
| 3282 | + # can be overridden. | ||
| 3283 | + | ||
| 3284 | + @classmethod | ||
| 3285 | + def new_figure_manager(cls, num, *args, **kwargs): | ||
| 3286 | + """Create a new figure manager instance. | ||
| 3287 | + """ | ||
| 3288 | + # This import needs to happen here due to circular imports. | ||
| 3289 | + from matplotlib.figure import Figure | ||
| 3290 | + fig_cls = kwargs.pop('FigureClass', Figure) | ||
| 3291 | + fig = fig_cls(*args, **kwargs) | ||
| 3292 | + return cls.new_figure_manager_given_figure(num, fig) | ||
| 3293 | + | ||
| 3294 | + @classmethod | ||
| 3295 | + def new_figure_manager_given_figure(cls, num, figure): | ||
| 3296 | + """Create a new figure manager instance for the given figure. | ||
| 3297 | + """ | ||
| 3298 | + canvas = cls.FigureCanvas(figure) | ||
| 3299 | + manager = cls.FigureManager(canvas, num) | ||
| 3300 | + return manager | ||
| 3301 | + | ||
| 3302 | + @classmethod | ||
| 3303 | + def draw_if_interactive(cls): | ||
| 3304 | + if cls.trigger_manager_draw is not None and is_interactive(): | ||
| 3305 | + manager = Gcf.get_active() | ||
| 3306 | + if manager: | ||
| 3307 | + cls.trigger_manager_draw(manager) | ||
| 3308 | + | ||
| 3309 | + @classmethod | ||
| 3310 | + def show(cls, block=None): | ||
| 3311 | + """Show all figures. | ||
| 3312 | + | ||
| 3313 | + `show` blocks by calling `mainloop` if *block* is ``True``, or if it | ||
| 3314 | + is ``None`` and we are neither in IPython's ``%pylab`` mode, nor in | ||
| 3315 | + `interactive` mode. | ||
| 3316 | + """ | ||
| 3317 | + if cls.mainloop is None: | ||
| 3318 | + frame = inspect.currentframe() | ||
| 3319 | + while frame: | ||
| 3320 | + if frame.f_code.co_filename in [ | ||
| 3321 | + "<stdin>", "<ipython console>"]: | ||
| 3322 | + warnings.warn("""\ | ||
| 3323 | + Your currently selected backend does not support show(). | ||
| 3324 | + Please select a GUI backend in your matplotlibrc file ('{}') | ||
| 3325 | + or with matplotlib.use()""".format(matplotlib.matplotlib_fname())) | ||
| 3326 | + break | ||
| 3327 | + else: | ||
| 3328 | + frame = frame.f_back | ||
| 3329 | + return | ||
| 3330 | + managers = Gcf.get_all_fig_managers() | ||
| 3331 | + if not managers: | ||
| 3332 | + return | ||
| 3333 | + for manager in managers: | ||
| 3334 | + manager.show() | ||
| 3335 | + if block is None: | ||
| 3336 | + # Hack: Are we in IPython's pylab mode? | ||
| 3337 | + from matplotlib import pyplot | ||
| 3338 | + try: | ||
| 3339 | + # IPython versions >= 0.10 tack the _needmain attribute onto | ||
| 3340 | + # pyplot.show, and always set it to False, when in %pylab mode. | ||
| 3341 | + ipython_pylab = not pyplot.show._needmain | ||
| 3342 | + except AttributeError: | ||
| 3343 | + ipython_pylab = False | ||
| 3344 | + block = not ipython_pylab and not is_interactive() | ||
| 3345 | + # TODO: The above is a hack to get the WebAgg backend working with | ||
| 3346 | + # ipython's `%pylab` mode until proper integration is implemented. | ||
| 3347 | + if get_backend() == "WebAgg": | ||
| 3348 | + block = True | ||
| 3349 | + if block: | ||
| 3350 | + cls.mainloop() | ||
| 3351 | + | ||
| 3352 | + # This method is the one actually exporting the required methods. | ||
| 3353 | + | ||
| 3354 | + @staticmethod | ||
| 3355 | + def export(cls): | ||
| 3356 | + for name in ["backend_version", | ||
| 3357 | + "FigureCanvas", | ||
| 3358 | + "FigureManager", | ||
| 3359 | + "new_figure_manager", | ||
| 3360 | + "new_figure_manager_given_figure", | ||
| 3361 | + "draw_if_interactive", | ||
| 3362 | + "show"]: | ||
| 3363 | + setattr(sys.modules[cls.__module__], name, getattr(cls, name)) | ||
| 3364 | + | ||
| 3365 | + # For back-compatibility, generate a shim `Show` class. | ||
| 3366 | + | ||
| 3367 | + class Show(ShowBase): | ||
| 3368 | + def mainloop(self): | ||
| 3369 | + return cls.mainloop() | ||
| 3370 | + | ||
| 3371 | + setattr(sys.modules[cls.__module__], "Show", Show) | ||
| 3372 | + return cls | ||
| 3373 | + | ||
| 3374 | + | ||
| 3375 | + class ShowBase(_Backend): | ||
| 3376 | + """ | ||
| 3377 | + Simple base class to generate a show() callable in backends. | ||
| 3378 | + | ||
| 3379 | + Subclass must override mainloop() method. | ||
| 3380 | + """ | ||
| 3381 | + | ||
| 3382 | + def __call__(self, block=None): | ||
| 3383 | + return self.show(block=block) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,10 +3,11 @@ | |||
| 3 | 3 | ||
| 4 | 4 | import six | |
| 5 | 5 | ||
| 6 | - import matplotlib | ||
| 7 | - import inspect | ||
| 6 | + import importlib | ||
| 8 | 7 | import traceback | |
| 9 | - import warnings | ||
| 8 | + | ||
| 9 | + import matplotlib | ||
| 10 | + from matplotlib.backend_bases import _Backend | ||
| 10 | 11 | ||
| 11 | 12 | ||
| 12 | 13 | backend = matplotlib.get_backend() | |
@@ -45,51 +46,31 @@ def pylab_setup(name=None): | |||
| 45 | 46 | ''' | |
| 46 | 47 | # Import the requested backend into a generic module object | |
| 47 | 48 | if name is None: | |
| 48 | - # validates, to match all_backends | ||
| 49 | 49 | name = matplotlib.get_backend() | |
| 50 | - if name.startswith('module://'): | ||
| 51 | - backend_name = name[9:] | ||
| 52 | - else: | ||
| 53 | - backend_name = 'backend_' + name | ||
| 54 | - backend_name = backend_name.lower() # until we banish mixed case | ||
| 55 | - backend_name = 'matplotlib.backends.%s' % backend_name.lower() | ||
| 56 | - | ||
| 57 | - # the last argument is specifies whether to use absolute or relative | ||
| 58 | - # imports. 0 means only perform absolute imports. | ||
| 59 | - backend_mod = __import__(backend_name, globals(), locals(), | ||
| 60 | - [backend_name], 0) | ||
| 61 | - | ||
| 62 | - # Things we pull in from all backends | ||
| 63 | - new_figure_manager = backend_mod.new_figure_manager | ||
| 64 | - | ||
| 65 | - # image backends like pdf, agg or svg do not need to do anything | ||
| 66 | - # for "show" or "draw_if_interactive", so if they are not defined | ||
| 67 | - # by the backend, just do nothing | ||
| 68 | - def do_nothing_show(*args, **kwargs): | ||
| 69 | - frame = inspect.currentframe() | ||
| 70 | - fname = frame.f_back.f_code.co_filename | ||
| 71 | - if fname in ('<stdin>', '<ipython console>'): | ||
| 72 | - warnings.warn(""" | ||
| 73 | - Your currently selected backend, '%s' does not support show(). | ||
| 74 | - Please select a GUI backend in your matplotlibrc file ('%s') | ||
| 75 | - or with matplotlib.use()""" % | ||
| 76 | - (name, matplotlib.matplotlib_fname())) | ||
| 77 | - | ||
| 78 | - def do_nothing(*args, **kwargs): | ||
| 79 | - pass | ||
| 80 | - | ||
| 81 | - backend_version = getattr(backend_mod, 'backend_version', 'unknown') | ||
| 82 | - | ||
| 83 | - show = getattr(backend_mod, 'show', do_nothing_show) | ||
| 84 | - | ||
| 85 | - draw_if_interactive = getattr(backend_mod, 'draw_if_interactive', | ||
| 86 | - do_nothing) | ||
| 50 | + backend_name = (name[9:] if name.startswith("module://") | ||
| 51 | + else "matplotlib.backends.backend_{}".format(name.lower())) | ||
| 87 | 52 | ||
| 53 | + backend_mod = importlib.import_module(backend_name) | ||
| 54 | + Backend = type(str("Backend"), (_Backend,), vars(backend_mod)) | ||
| 88 | 55 | matplotlib.verbose.report('backend %s version %s' % | |
| 89 | - (name, backend_version)) | ||
| 56 | + (name, Backend.backend_version)) | ||
| 90 | 57 | ||
| 91 | 58 | # need to keep a global reference to the backend for compatibility | |
| 92 | 59 | # reasons. See https://github.com/matplotlib/matplotlib/issues/6092 | |
| 93 | 60 | global backend | |
| 94 | 61 | backend = name | |
| 95 | - return backend_mod, new_figure_manager, draw_if_interactive, show | ||
| 62 | + | ||
| 63 | + # We want to get functions out of a class namespace and call them *without | ||
| 64 | + # the first argument being an instance of the class*. This works directly | ||
| 65 | + # on Py3. On Py2, we need to remove the check that the first argument | ||
| 66 | + # be an instance of the class. The only relevant case is if `.im_self` | ||
| 67 | + # is None (if we have a bound method (e.g. a classmethod), everything is | ||
| 68 | + # fine.) | ||
| 69 | + def _dont_check_first_arg(func): | ||
| 70 | + return (func.im_func if getattr(func, "im_self", 0) is None | ||
| 71 | + else func) | ||
| 72 | + | ||
| 73 | + return (backend_mod, | ||
| 74 | + _dont_check_first_arg(Backend.new_figure_manager), | ||
| 75 | + _dont_check_first_arg(Backend.draw_if_interactive), | ||
| 76 | + _dont_check_first_arg(Backend.show)) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2599,11 +2599,9 @@ def print_pdf(self, filename, **kwargs): | |||
| 2599 | 2599 | file.close() | |
| 2600 | 2600 | ||
| 2601 | 2601 | ||
| 2602 | - class FigureManagerPdf(FigureManagerBase): | ||
| 2603 | - pass | ||
| 2602 | + FigureManagerPdf = FigureManagerBase | ||
| 2604 | 2603 | ||
| 2605 | 2604 | ||
| 2606 | 2605 | @_Backend.export | |
| 2607 | 2606 | class _BackendPdf(_Backend): | |
| 2608 | 2607 | FigureCanvas = FigureCanvasPdf | |
| 2609 | - FigureManager = FigureManagerPdf | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1728,8 +1728,7 @@ def pstoeps(tmpfile, bbox=None, rotated=False): | |||
| 1728 | 1728 | shutil.move(epsfile, tmpfile) | |
| 1729 | 1729 | ||
| 1730 | 1730 | ||
| 1731 | - class FigureManagerPS(FigureManagerBase): | ||
| 1732 | - pass | ||
| 1731 | + FigureManagerPS = FigureManagerBase | ||
| 1733 | 1732 | ||
| 1734 | 1733 | ||
| 1735 | 1734 | # The following Python dictionary psDefs contains the entries for the | |
@@ -1775,4 +1774,3 @@ class FigureManagerPS(FigureManagerBase): | |||
| 1775 | 1774 | @_Backend.export | |
| 1776 | 1775 | class _BackendPS(_Backend): | |
| 1777 | 1776 | FigureCanvas = FigureCanvasPS | |
| 1778 | - FigureManager = FigureManagerPS | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1251,8 +1251,8 @@ def _print_svg(self, filename, svgwriter, **kwargs): | |||
| 1251 | 1251 | def get_default_filetype(self): | |
| 1252 | 1252 | return 'svg' | |
| 1253 | 1253 | ||
| 1254 | - class FigureManagerSVG(FigureManagerBase): | ||
| 1255 | - pass | ||
| 1254 | + | ||
| 1255 | + FigureManagerSVG = FigureManagerBase | ||
| 1256 | 1256 | ||
| 1257 | 1257 | ||
| 1258 | 1258 | svgProlog = """\ | |
@@ -1266,4 +1266,3 @@ class FigureManagerSVG(FigureManagerBase): | |||
| 1266 | 1266 | @_Backend.export | |
| 1267 | 1267 | class _BackendSVG(_Backend): | |
| 1268 | 1268 | FigureCanvas = FigureCanvasSVG | |
| 1269 | - FigureManager = FigureManagerSVG | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments