From 5141f80e09d64110a72dc4e6cb9e467d153e9ad7 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Wed, 14 Jun 2017 01:50:08 -0700 Subject: [PATCH] Backend class to factor out common code. --- lib/matplotlib/backend_bases.py | 148 ++++++++++++------ lib/matplotlib/backends/backend_agg.py | 27 +--- lib/matplotlib/backends/backend_cairo.py | 34 ++-- lib/matplotlib/backends/backend_gdk.py | 27 +--- lib/matplotlib/backends/backend_gtk.py | 61 +++----- lib/matplotlib/backends/backend_gtk3.py | 38 ++--- lib/matplotlib/backends/backend_gtk3agg.py | 29 +--- lib/matplotlib/backends/backend_gtk3cairo.py | 36 ++--- lib/matplotlib/backends/backend_gtkagg.py | 42 +---- lib/matplotlib/backends/backend_gtkcairo.py | 29 ++-- lib/matplotlib/backends/backend_macosx.py | 61 +++----- lib/matplotlib/backends/backend_nbagg.py | 129 ++++++--------- lib/matplotlib/backends/backend_pdf.py | 33 +--- lib/matplotlib/backends/backend_pgf.py | 37 +---- lib/matplotlib/backends/backend_ps.py | 27 +--- lib/matplotlib/backends/backend_qt4.py | 41 +---- lib/matplotlib/backends/backend_qt4agg.py | 28 +--- lib/matplotlib/backends/backend_qt5.py | 71 +++------ lib/matplotlib/backends/backend_qt5agg.py | 27 +--- lib/matplotlib/backends/backend_svg.py | 26 +-- lib/matplotlib/backends/backend_template.py | 16 +- lib/matplotlib/backends/backend_tkagg.py | 106 ++++++------- lib/matplotlib/backends/backend_webagg.py | 74 +++------ .../backends/backend_webagg_core.py | 25 +-- lib/matplotlib/backends/backend_wx.py | 115 +++++--------- lib/matplotlib/backends/backend_wxagg.py | 42 +---- 26 files changed, 470 insertions(+), 859 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 7dcfbf3fcf51..bca46679d5f8 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -55,8 +55,8 @@ from matplotlib import rcParams from matplotlib import is_interactive from matplotlib import get_backend -from matplotlib._pylab_helpers import Gcf from matplotlib import lines +from matplotlib._pylab_helpers import Gcf from matplotlib.transforms import Bbox, TransformedBbox, Affine2D @@ -141,60 +141,118 @@ def get_registered_canvas_class(format): return backend_class -class ShowBase(object): - """ - Simple base class to generate a show() callable in backends. +class _Backend(object): + # A backend can be defined by using the following pattern: + # + # @_Backend.export + # class FooBackend(_Backend): + # # override the attributes and methods documented below. - Subclass must override mainloop() method. - """ - def __call__(self, block=None): + # The following attributes and methods must be overridden by subclasses. + + # The `FigureCanvas` and `FigureManager` classes must be defined. + FigureCanvas = None + FigureManager = None + + # The following methods must be left as None for non-interactive backends. + # For interactive backends, `trigger_manager_draw` should be a function + # taking a manager as argument and triggering a canvas draw, and `mainloop` + # should be a function taking no argument and starting the backend main + # loop. + trigger_manager_draw = None + mainloop = None + + # The following methods will be automatically defined and exported, but + # can be overridden. + + @classmethod + def new_figure_manager(cls, num, *args, **kwargs): + """Create a new figure manager instance. + """ + # This import needs to happen here due to circular imports. + from matplotlib.figure import Figure + fig_cls = kwargs.pop('FigureClass', Figure) + fig = fig_cls(*args, **kwargs) + return cls.new_figure_manager_given_figure(num, fig) + + @classmethod + def new_figure_manager_given_figure(cls, num, figure): + """Create a new figure manager instance for the given figure. """ - Show all figures. If *block* is not None, then - it is a boolean that overrides all other factors - determining whether show blocks by calling mainloop(). - The other factors are: - it does not block if run inside ipython's "%pylab" mode - it does not block in interactive mode. + canvas = cls.FigureCanvas(figure) + manager = cls.FigureManager(canvas, num) + return manager + + @classmethod + def draw_if_interactive(cls): + if cls.trigger_manager_draw is not None and is_interactive(): + manager = Gcf.get_active() + if manager: + cls.trigger_manager_draw(manager) + + @classmethod + def show(cls, block=None): + """Show all figures. + + `show` blocks by calling `mainloop` if *block* is ``True``, or if it + is ``None`` and we are neither in IPython's ``%pylab`` mode, nor in + `interactive` mode. """ + if cls.mainloop is None: + return managers = Gcf.get_all_fig_managers() if not managers: return - for manager in managers: manager.show() + if block is None: + # Hack: Are we in IPython's pylab mode? + from matplotlib import pyplot + try: + # IPython versions >= 0.10 tack the _needmain attribute onto + # pyplot.show, and always set it to False, when in %pylab mode. + ipython_pylab = not pyplot.show._needmain + except AttributeError: + ipython_pylab = False + block = not ipython_pylab and not is_interactive() + # TODO: The above is a hack to get the WebAgg backend working with + # ipython's `%pylab` mode until proper integration is implemented. + if get_backend() == "WebAgg": + block = True + if block: + cls.mainloop() + + # This method is the one actually exporting the required methods. + + @staticmethod + def export(cls): + for name in ["FigureCanvas", + "FigureManager", + "new_figure_manager", + "new_figure_manager_given_figure", + "draw_if_interactive", + "show"]: + setattr(sys.modules[cls.__module__], name, getattr(cls, name)) + + # For back-compatibility, generate a shim `Show` class. + + class Show(ShowBase): + def mainloop(self): + return cls.mainloop() + + setattr(sys.modules[cls.__module__], "Show", Show) + return cls + + +class ShowBase(_Backend): + """ + Simple base class to generate a show() callable in backends. - if block is not None: - if block: - self.mainloop() - return - else: - return - - # Hack: determine at runtime whether we are - # inside ipython in pylab mode. - from matplotlib import pyplot - try: - ipython_pylab = not pyplot.show._needmain - # IPython versions >= 0.10 tack the _needmain - # attribute onto pyplot.show, and always set - # it to False, when in %pylab mode. - ipython_pylab = ipython_pylab and get_backend() != 'WebAgg' - # TODO: The above is a hack to get the WebAgg backend - # working with ipython's `%pylab` mode until proper - # integration is implemented. - except AttributeError: - ipython_pylab = False - - # Leave the following as a separate step in case we - # want to control this behavior with an rcParam. - if ipython_pylab: - return - - if not is_interactive() or get_backend() == 'WebAgg': - self.mainloop() + Subclass must override mainloop() method. + """ - def mainloop(self): - pass + def __call__(self, block=None): + return self.show(block=block) class RendererBase(object): diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py index b0c876418344..a811401380c7 100644 --- a/lib/matplotlib/backends/backend_agg.py +++ b/lib/matplotlib/backends/backend_agg.py @@ -29,8 +29,8 @@ from collections import OrderedDict from math import radians, cos, sin from matplotlib import verbose, rcParams, __version__ -from matplotlib.backend_bases import (RendererBase, FigureManagerBase, - FigureCanvasBase) +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, RendererBase) from matplotlib.cbook import maxdict, restrict_dict from matplotlib.figure import Figure from matplotlib.font_manager import findfont, get_font @@ -394,24 +394,6 @@ def post_processing(image, dpi): gc, l + ox, height - b - h + oy, img) -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasAgg(figure) - manager = FigureManagerBase(canvas, num) - return manager - - class FigureCanvasAgg(FigureCanvasBase): """ The canvas the figure renders into. Calls the draw and print fig @@ -606,4 +588,7 @@ def print_tif(self, filename_or_obj, *args, **kwargs): print_tiff = print_tif -FigureCanvas = FigureCanvasAgg +@_Backend.export +class _BackendAgg(_Backend): + FigureCanvas = FigureCanvasAgg + FigureManager = FigureManagerBase diff --git a/lib/matplotlib/backends/backend_cairo.py b/lib/matplotlib/backends/backend_cairo.py index 9318cca4f885..c513872a588c 100644 --- a/lib/matplotlib/backends/backend_cairo.py +++ b/lib/matplotlib/backends/backend_cairo.py @@ -52,11 +52,12 @@ del _version_required from matplotlib.backend_bases import ( - RendererBase, GraphicsContextBase, FigureManagerBase, FigureCanvasBase) -from matplotlib.figure import Figure -from matplotlib.mathtext import MathTextParser -from matplotlib.path import Path -from matplotlib.transforms import Bbox, Affine2D + _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase, + RendererBase) +from matplotlib.figure import Figure +from matplotlib.mathtext import MathTextParser +from matplotlib.path import Path +from matplotlib.transforms import Bbox, Affine2D from matplotlib.font_manager import ttfFontProperty @@ -452,24 +453,6 @@ def set_linewidth(self, w): self.ctx.set_line_width(self.renderer.points_to_pixels(w)) -def new_figure_manager(num, *args, **kwargs): # called by backends/__init__.py - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasCairo(figure) - manager = FigureManagerBase(canvas, num) - return manager - - class FigureCanvasCairo(FigureCanvasBase): def print_png(self, fobj, *args, **kwargs): width, height = self.get_width_height() @@ -555,4 +538,7 @@ def _save(self, fo, fmt, **kwargs): fo.close() -FigureCanvas = FigureCanvasCairo +@_Backend.export +class _BackendCairo(_Backend): + FigureCanvas = FigureCanvasCairo + FigureManager = FigureManagerBase diff --git a/lib/matplotlib/backends/backend_gdk.py b/lib/matplotlib/backends/backend_gdk.py index 8e9d424a8075..768d3201647f 100644 --- a/lib/matplotlib/backends/backend_gdk.py +++ b/lib/matplotlib/backends/backend_gdk.py @@ -24,7 +24,8 @@ from matplotlib import rcParams from matplotlib._pylab_helpers import Gcf from matplotlib.backend_bases import ( - RendererBase, GraphicsContextBase, FigureManagerBase, FigureCanvasBase) + _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase, + RendererBase) from matplotlib.cbook import restrict_dict, warn_deprecated from matplotlib.figure import Figure from matplotlib.mathtext import MathTextParser @@ -381,24 +382,6 @@ def set_linewidth(self, w): self.gdkGC.line_width = max(1, int(np.round(pixels))) -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasGDK(figure) - manager = FigureManagerBase(canvas, num) - return manager - - class FigureCanvasGDK (FigureCanvasBase): def __init__(self, figure): FigureCanvasBase.__init__(self, figure) @@ -452,3 +435,9 @@ def _print_image(self, filename, format, *args, **kwargs): options['quality'] = str(options['quality']) pixbuf.save(filename, format, options=options) + + +@_Backend.export +class _BackendGDK(_Backend): + FigureCanvas = FigureCanvasGDK + FigureManager = FigureManagerBase diff --git a/lib/matplotlib/backends/backend_gtk.py b/lib/matplotlib/backends/backend_gtk.py index a5dec05faeaa..b3f7ec504bca 100644 --- a/lib/matplotlib/backends/backend_gtk.py +++ b/lib/matplotlib/backends/backend_gtk.py @@ -28,15 +28,14 @@ import matplotlib from matplotlib._pylab_helpers import Gcf -from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \ - FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors, TimerBase -from matplotlib.backend_bases import ShowBase +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2, + TimerBase, cursors) from matplotlib.backends.backend_gdk import RendererGDK, FigureCanvasGDK -from matplotlib.cbook import is_writable_file_like +from matplotlib.cbook import is_writable_file_like, warn_deprecated from matplotlib.figure import Figure from matplotlib.widgets import SubplotTool -from matplotlib.cbook import warn_deprecated from matplotlib import ( cbook, colors as mcolors, lines, markers, rcParams, verbose) @@ -63,41 +62,6 @@ def GTK_WIDGET_DRAWABLE(w): return flags & gtk.VISIBLE != 0 and flags & gtk.MAPPED != 0 -def draw_if_interactive(): - """ - Is called after every pylab drawing command - """ - if matplotlib.is_interactive(): - figManager = Gcf.get_active() - if figManager is not None: - figManager.canvas.draw_idle() - - -class Show(ShowBase): - def mainloop(self): - if gtk.main_level() == 0: - gtk.main() - -show = Show() - -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasGTK(figure) - manager = FigureManagerGTK(canvas, num) - return manager - - class TimerGTK(TimerBase): ''' Subclass of :class:`backend_bases.TimerBase` using GTK for timer events. @@ -521,6 +485,7 @@ def stop_event_loop(self): FigureCanvasBase.stop_event_loop_default(self) stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__ + class FigureManagerGTK(FigureManagerBase): """ Attributes @@ -866,6 +831,7 @@ def get_filename_from_user (self): return filename, self.ext + class DialogLineprops(object): """ A GUI dialog for controlling lineprops @@ -1056,5 +1022,16 @@ def error_msg_gtk(msg, parent=None): dialog.destroy() -FigureCanvas = FigureCanvasGTK -FigureManager = FigureManagerGTK +@_Backend.export +class _BackendGTK(_Backend): + FigureCanvas = FigureCanvasGTK + FigureManager = FigureManagerGTK + + @staticmethod + def trigger_manager_draw(manager): + manager.canvas.draw_idle() + + @staticmethod + def mainloop(): + if gtk.main_level() == 0: + gtk.main() diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index 4e53c1a4ee2e..a5f223a38753 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -28,10 +28,9 @@ import matplotlib from matplotlib._pylab_helpers import Gcf from matplotlib.backend_bases import ( - FigureCanvasBase, FigureManagerBase, GraphicsContextBase, + _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase, NavigationToolbar2, RendererBase, TimerBase, cursors) -from matplotlib.backend_bases import ( - ShowBase, ToolContainerBase, StatusbarBase) +from matplotlib.backend_bases import ToolContainerBase, StatusbarBase from matplotlib.backend_managers import ToolManager from matplotlib.cbook import is_writable_file_like from matplotlib.figure import Figure @@ -54,22 +53,6 @@ cursors.SELECT_REGION : Gdk.Cursor.new(Gdk.CursorType.TCROSS), } -def draw_if_interactive(): - """ - Is called after every pylab drawing command - """ - if matplotlib.is_interactive(): - figManager = Gcf.get_active() - if figManager is not None: - figManager.canvas.draw_idle() - -class Show(ShowBase): - def mainloop(self): - if Gtk.main_level() == 0: - Gtk.main() - -show = Show() - class TimerGTK3(TimerBase): ''' @@ -947,5 +930,18 @@ def error_msg_gtk(msg, parent=None): backend_tools.ToolRubberband = RubberbandGTK3 Toolbar = ToolbarGTK3 -FigureCanvas = FigureCanvasGTK3 -FigureManager = FigureManagerGTK3 + + +@_Backend.export +class _BackendGTK3(_Backend): + FigureCanvas = FigureCanvasGTK3 + FigureManager = FigureManagerGTK3 + + @staticmethod + def trigger_manager_draw(manager): + manager.canvas.draw_idle() + + @staticmethod + def mainloop(): + if Gtk.main_level() == 0: + Gtk.main() diff --git a/lib/matplotlib/backends/backend_gtk3agg.py b/lib/matplotlib/backends/backend_gtk3agg.py index f60ac9b8154d..a8bce0c4e6fc 100644 --- a/lib/matplotlib/backends/backend_gtk3agg.py +++ b/lib/matplotlib/backends/backend_gtk3agg.py @@ -6,9 +6,9 @@ import numpy as np import warnings -from . import backend_agg -from . import backend_gtk3 +from . import backend_agg, backend_gtk3 from .backend_cairo import cairo, HAS_CAIRO_CFFI +from .backend_gtk3 import _BackendGTK3 from matplotlib.figure import Figure from matplotlib import transforms @@ -97,24 +97,7 @@ class FigureManagerGTK3Agg(backend_gtk3.FigureManagerGTK3): pass -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasGTK3Agg(figure) - manager = FigureManagerGTK3Agg(canvas, num) - return manager - - -FigureCanvas = FigureCanvasGTK3Agg -FigureManager = FigureManagerGTK3Agg -show = backend_gtk3.show +@_BackendGTK3.export +class _BackendGTK3Cairo(_BackendGTK3): + FigureCanvas = FigureCanvasGTK3Agg + FigureManager = FigureManagerGTK3Agg diff --git a/lib/matplotlib/backends/backend_gtk3cairo.py b/lib/matplotlib/backends/backend_gtk3cairo.py index b01f51b638ad..958689d8e6ba 100644 --- a/lib/matplotlib/backends/backend_gtk3cairo.py +++ b/lib/matplotlib/backends/backend_gtk3cairo.py @@ -3,11 +3,12 @@ import six -from . import backend_gtk3 -from . import backend_cairo +from . import backend_cairo, backend_gtk3 from .backend_cairo import cairo, HAS_CAIRO_CFFI +from .backend_gtk3 import _BackendGTK3 from matplotlib.figure import Figure + class RendererGTK3Cairo(backend_cairo.RendererCairo): def set_context(self, ctx): if HAS_CAIRO_CFFI: @@ -22,16 +23,14 @@ def set_context(self, ctx): class FigureCanvasGTK3Cairo(backend_gtk3.FigureCanvasGTK3, backend_cairo.FigureCanvasCairo): - def __init__(self, figure): - backend_gtk3.FigureCanvasGTK3.__init__(self, figure) def _renderer_init(self): """use cairo renderer""" self._renderer = RendererGTK3Cairo(self.figure.dpi) def _render_figure(self, width, height): - self._renderer.set_width_height (width, height) - self.figure.draw (self._renderer) + self._renderer.set_width_height(width, height) + self.figure.draw(self._renderer) def on_draw_event(self, widget, ctx): """ GtkDrawable draw event, like expose_event in GTK 2.X @@ -47,24 +46,7 @@ class FigureManagerGTK3Cairo(backend_gtk3.FigureManagerGTK3): pass -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasGTK3Cairo(figure) - manager = FigureManagerGTK3Cairo(canvas, num) - return manager - - -FigureCanvas = FigureCanvasGTK3Cairo -FigureManager = FigureManagerGTK3Cairo -show = backend_gtk3.show +@_BackendGTK3.export +class _BackendGTK3Cairo(_BackendGTK3): + FigureCanvas = FigureCanvasGTK3Cairo + FigureManager = FigureManagerGTK3Cairo diff --git a/lib/matplotlib/backends/backend_gtkagg.py b/lib/matplotlib/backends/backend_gtkagg.py index f89a426c6eb9..aef7593fea63 100644 --- a/lib/matplotlib/backends/backend_gtkagg.py +++ b/lib/matplotlib/backends/backend_gtkagg.py @@ -11,10 +11,9 @@ import matplotlib from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg -from matplotlib.backends.backend_gtk import gtk, FigureManagerGTK, FigureCanvasGTK,\ - show, draw_if_interactive,\ - error_msg_gtk, PIXELS_PER_INCH, backend_version, \ - NavigationToolbar2GTK +from matplotlib.backends.backend_gtk import ( + gtk, _BackendGTK, FigureCanvasGTK, FigureManagerGTK, NavigationToolbar2GTK, + backend_version, error_msg_gtk, PIXELS_PER_INCH) from matplotlib.backends._gtkagg import agg_to_gtk_drawable @@ -36,26 +35,6 @@ def _get_toolbar(self, canvas): return toolbar -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - if DEBUG: print('backend_gtkagg.new_figure_manager') - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasGTKAgg(figure) - figuremanager = FigureManagerGTKAgg(canvas, num) - if DEBUG: print('backend_gtkagg.new_figure_manager done') - return figuremanager - - class FigureCanvasGTKAgg(FigureCanvasGTK, FigureCanvasAgg): filetypes = FigureCanvasGTK.filetypes.copy() filetypes.update(FigureCanvasAgg.filetypes) @@ -115,14 +94,7 @@ def print_png(self, filename, *args, **kwargs): return agg.print_png(filename, *args, **kwargs) -"""\ -Traceback (most recent call last): - File "/home/titan/johnh/local/lib/python2.3/site-packages/matplotlib/backends/backend_gtk.py", line 304, in expose_event - self._render_figure(self._pixmap, w, h) - File "/home/titan/johnh/local/lib/python2.3/site-packages/matplotlib/backends/backend_gtkagg.py", line 77, in _render_figure - pixbuf = gtk.gdk.pixbuf_new_from_data( -ValueError: data length (3156672) is less then required by the other parameters (3160608) -""" - -FigureCanvas = FigureCanvasGTKAgg -FigureManager = FigureManagerGTKAgg +@_BackendGTK.export +class _BackendGTKAgg(_BackendGTK): + FigureCanvas = FigureCanvasGTKAgg + FigureManager = FigureManagerGTKAgg diff --git a/lib/matplotlib/backends/backend_gtkcairo.py b/lib/matplotlib/backends/backend_gtkcairo.py index 1440b85044a9..a8cdf076a93f 100644 --- a/lib/matplotlib/backends/backend_gtkcairo.py +++ b/lib/matplotlib/backends/backend_gtkcairo.py @@ -11,30 +11,15 @@ if gtk.pygtk_version < (2, 7, 0): import cairo.gtk +from matplotlib import cbook from matplotlib.backends import backend_cairo from matplotlib.backends.backend_gtk import * +from matplotlib.backends.backend_gtk import _BackendGTK backend_version = ('PyGTK(%d.%d.%d) ' % gtk.pygtk_version + 'Pycairo(%s)' % backend_cairo.backend_version) -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasGTKCairo(figure) - return FigureManagerGTK(canvas, num) - - class RendererGTKCairo (backend_cairo.RendererCairo): if gtk.pygtk_version >= (2,7,0): def set_pixmap (self, pixmap): @@ -53,6 +38,8 @@ def _renderer_init(self): self._renderer = RendererGTKCairo(self.figure.dpi) +# This class has been unused for a while at least. +@cbook.deprecated("2.1") class FigureManagerGTKCairo(FigureManagerGTK): def _get_toolbar(self, canvas): # must be inited after the window, drawingArea and figure @@ -64,10 +51,14 @@ def _get_toolbar(self, canvas): return toolbar +# This class has been unused for a while at least. +@cbook.deprecated("2.1") class NavigationToolbar2Cairo(NavigationToolbar2GTK): def _get_canvas(self, fig): return FigureCanvasGTKCairo(fig) -FigureCanvas = FigureCanvasGTKCairo -FigureManager = FigureManagerGTKCairo +@_BackendGTK.export +class _BackendGTKCairo(_BackendGTK): + FigureCanvas = FigureCanvasGTKCairo + FigureManager = FigureManagerGTK diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index e093e2799b8d..61e07a010b92 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -6,9 +6,9 @@ import os from matplotlib._pylab_helpers import Gcf -from matplotlib.backend_bases import FigureManagerBase, FigureCanvasBase, \ - NavigationToolbar2, TimerBase -from matplotlib.backend_bases import ShowBase +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2, + TimerBase) from matplotlib.figure import Figure from matplotlib import rcParams @@ -21,12 +21,6 @@ from .backend_agg import RendererAgg, FigureCanvasAgg -class Show(ShowBase): - def mainloop(self): - _macosx.show() -show = Show() - - ######################################################################## # # The following functions and classes are for pylab and implement @@ -34,37 +28,6 @@ def mainloop(self): # ######################################################################## -def draw_if_interactive(): - """ - For performance reasons, we don't want to redraw the figure after - each draw command. Instead, we mark the figure as invalid, so that - it will be redrawn as soon as the event loop resumes via PyOS_InputHook. - This function should be called after each draw event, even if - matplotlib is not running interactively. - """ - if matplotlib.is_interactive(): - figManager = Gcf.get_active() - if figManager is not None: - figManager.canvas.invalidate() - - -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - figure = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, figure) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasMac(figure) - manager = FigureManagerMac(canvas, num) - return manager - class TimerMac(_macosx.Timer, TimerBase): ''' @@ -248,5 +211,19 @@ def set_message(self, message): # ######################################################################## -FigureCanvas = FigureCanvasMac -FigureManager = FigureManagerMac +@_Backend.export +class _BackendMac(_Backend): + FigureCanvas = FigureCanvasMac + FigureManager = FigureManagerMac + + def trigger_manager_draw(manager): + # For performance reasons, we don't want to redraw the figure after + # each draw command. Instead, we mark the figure as invalid, so that it + # will be redrawn as soon as the event loop resumes via PyOS_InputHook. + # This function should be called after each draw event, even if + # matplotlib is not running interactively. + manager.canvas.invalidate() + + @staticmethod + def mainloop(): + _macosx.show() diff --git a/lib/matplotlib/backends/backend_nbagg.py b/lib/matplotlib/backends/backend_nbagg.py index 3f5ba467fcfc..7274ad688879 100644 --- a/lib/matplotlib/backends/backend_nbagg.py +++ b/lib/matplotlib/backends/backend_nbagg.py @@ -25,51 +25,14 @@ from IPython.utils.traitlets import Unicode, Bool, Float, List, Any from IPython.html.nbextensions import install_nbextension -from matplotlib import rcParams +from matplotlib import rcParams, is_interactive +from matplotlib._pylab_helpers import Gcf +from matplotlib.backends.backend_webagg_core import ( + FigureCanvasWebAggCore, FigureManagerWebAgg, NavigationToolbar2WebAgg, + TimerTornado) +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, NavigationToolbar2) from matplotlib.figure import Figure -from matplotlib import is_interactive -from matplotlib.backends.backend_webagg_core import (FigureManagerWebAgg, - FigureCanvasWebAggCore, - NavigationToolbar2WebAgg, - TimerTornado) -from matplotlib.backend_bases import (ShowBase, NavigationToolbar2, - FigureCanvasBase) - - -class Show(ShowBase): - - def __call__(self, block=None): - from matplotlib._pylab_helpers import Gcf - - managers = Gcf.get_all_fig_managers() - if not managers: - return - - interactive = is_interactive() - - for manager in managers: - manager.show() - - # plt.figure adds an event which puts the figure in focus - # in the activeQue. Disable this behaviour, as it results in - # figures being put as the active figure after they have been - # shown, even in non-interactive mode. - if hasattr(manager, '_cidgcf'): - manager.canvas.mpl_disconnect(manager._cidgcf) - - if not interactive and manager in Gcf._activeQue: - Gcf._activeQue.remove(manager) - -show = Show() - - -def draw_if_interactive(): - import matplotlib._pylab_helpers as pylab_helpers - - if is_interactive(): - manager = pylab_helpers.Gcf.get_active() - if manager is not None: - manager.show() def connection_info(): @@ -79,7 +42,6 @@ def connection_info(): use. """ - from matplotlib._pylab_helpers import Gcf result = [] for manager in Gcf.get_all_fig_managers(): fig = manager.canvas.figure @@ -222,38 +184,6 @@ def destroy(self): self._send_event('close') -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - from .._pylab_helpers import Gcf - - def closer(event): - Gcf.destroy(num) - - canvas = FigureCanvasNbAgg(figure) - if rcParams['nbagg.transparent']: - figure.patch.set_alpha(0) - manager = FigureManagerNbAgg(canvas, num) - - if is_interactive(): - manager.show() - figure.canvas.draw_idle() - - canvas.mpl_connect('close_event', closer) - - return manager - - def nbinstall(overwrite=False, user=True): """ Copies javascript dependencies to the '/nbextensions' folder in @@ -296,4 +226,47 @@ def nbinstall(overwrite=False, user=True): **({'user': user} if version_info >= (3, 0, 0, '') else {}) ) -#nbinstall() + +@_Backend.export +class _BackendNbAgg(_Backend): + FigureCanvas = FigureCanvasNbAgg + FigureManager = FigureManagerNbAgg + + @staticmethod + def new_figure_manager_given_figure(num, figure): + canvas = FigureCanvasNbAgg(figure) + if rcParams['nbagg.transparent']: + figure.patch.set_alpha(0) + manager = FigureManagerNbAgg(canvas, num) + if is_interactive(): + manager.show() + figure.canvas.draw_idle() + canvas.mpl_connect('close_event', lambda event: Gcf.destroy(num)) + return manager + + @staticmethod + def trigger_manager_draw(manager): + manager.show() + + @staticmethod + def show(): + from matplotlib._pylab_helpers import Gcf + + managers = Gcf.get_all_fig_managers() + if not managers: + return + + interactive = is_interactive() + + for manager in managers: + manager.show() + + # plt.figure adds an event which puts the figure in focus + # in the activeQue. Disable this behaviour, as it results in + # figures being put as the active figure after they have been + # shown, even in non-interactive mode. + if hasattr(manager, '_cidgcf'): + manager.canvas.mpl_disconnect(manager._cidgcf) + + if not interactive and manager in Gcf._activeQue: + Gcf._activeQue.remove(manager) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index f41c95588b26..87a5c1e64de7 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -31,8 +31,9 @@ import matplotlib from matplotlib import __version__, rcParams from matplotlib._pylab_helpers import Gcf -from matplotlib.backend_bases import (RendererBase, GraphicsContextBase, - FigureManagerBase, FigureCanvasBase) +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase, + RendererBase) from matplotlib.backends.backend_mixed import MixedModeRenderer from matplotlib.cbook import (Bunch, get_realpath_and_stat, is_writable_file_like, maxdict) @@ -2425,28 +2426,6 @@ def finalize(self): ######################################################################## -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - # if a main-level app must be created, this is the usual place to - # do it -- see backend_wx, backend_wxagg and backend_tkagg for - # examples. Not all GUIs require explicit instantiation of a - # main-level app (egg backend_gtk, backend_gtkagg) for pylab - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasPdf(figure) - manager = FigureManagerPdf(canvas, num) - return manager - - class PdfPages(object): """ A multi-page PDF file. @@ -2624,5 +2603,7 @@ class FigureManagerPdf(FigureManagerBase): pass -FigureCanvas = FigureCanvasPdf -FigureManager = FigureManagerPdf +@_Backend.export +class _BackendPdf(_Backend): + FigureCanvas = FigureCanvasPdf + FigureManager = FigureManagerPdf diff --git a/lib/matplotlib/backends/backend_pgf.py b/lib/matplotlib/backends/backend_pgf.py index ac0c2d6c0ec0..6d57a3de4724 100644 --- a/lib/matplotlib/backends/backend_pgf.py +++ b/lib/matplotlib/backends/backend_pgf.py @@ -18,8 +18,9 @@ import numpy as np import matplotlib as mpl -from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ - FigureManagerBase, FigureCanvasBase +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase, + RendererBase) from matplotlib.backends.backend_mixed import MixedModeRenderer from matplotlib.figure import Figure from matplotlib.text import Text @@ -743,32 +744,6 @@ class GraphicsContextPgf(GraphicsContextBase): ######################################################################## -def draw_if_interactive(): - pass - - -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - # if a main-level app must be created, this is the usual place to - # do it -- see backend_wx, backend_wxagg and backend_tkagg for - # examples. Not all GUIs require explicit instantiation of a - # main-level app (egg backend_gtk, backend_gtkagg) for pylab - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasPgf(figure) - manager = FigureManagerPgf(canvas, num) - return manager - - class TmpDirCleaner(object): remaining_tmpdirs = set() @@ -976,8 +951,10 @@ def __init__(self, *args): FigureManagerBase.__init__(self, *args) -FigureCanvas = FigureCanvasPgf -FigureManager = FigureManagerPgf +@_Backend.export +class _BackendPgf(_Backend): + FigureCanvas = FigureCanvasPgf + FigureManager = FigureManagerPgf def _cleanup_all(): diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 0e4e2011841c..f34795566fda 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -14,8 +14,9 @@ from tempfile import mkstemp from matplotlib import verbose, __version__, rcParams, checkdep_ghostscript from matplotlib.afm import AFM -from matplotlib.backend_bases import (RendererBase, GraphicsContextBase, - FigureManagerBase, FigureCanvasBase) +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase, + RendererBase) from matplotlib.cbook import (get_realpath_and_stat, is_writable_file_like, maxdict, file_requires_unicode) @@ -891,21 +892,6 @@ def shouldstroke(self): (len(self.get_rgb()) <= 3 or self.get_rgb()[3] != 0.0)) -def new_figure_manager(num, *args, **kwargs): - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasPS(figure) - manager = FigureManagerPS(canvas, num) - return manager - - class FigureCanvasPS(FigureCanvasBase): _renderer_class = RendererPS @@ -1785,5 +1771,8 @@ class FigureManagerPS(FigureManagerBase): } bind def""", ] -FigureCanvas = FigureCanvasPS -FigureManager = FigureManagerPS + +@_Backend.export +class _BackendPS(_Backend): + FigureCanvas = FigureCanvasPS + FigureManager = FigureManagerPS diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index c90a36c2a648..cac4b2d744e7 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -8,50 +8,24 @@ import signal import sys -import matplotlib - -from matplotlib.backend_bases import FigureManagerBase -from matplotlib.backend_bases import FigureCanvasBase -from matplotlib.backend_bases import NavigationToolbar2 - -from matplotlib.backend_bases import cursors -from matplotlib.backend_bases import TimerBase -from matplotlib.backend_bases import ShowBase - from matplotlib._pylab_helpers import Gcf +from matplotlib.backend_bases import ( + FigureCanvasBase, FigureManagerBase, NavigationToolbar2, TimerBase, + cursors) from matplotlib.figure import Figure - from matplotlib.widgets import SubplotTool from .qt_compat import QtCore, QtWidgets, _getSaveFileName, __version__ from .backend_qt5 import ( backend_version, SPECIAL_KEYS, SUPER, ALT, CTRL, SHIFT, MODIFIER_KEYS, - cursord, draw_if_interactive, _create_qApp, show, TimerQT, MainWindow, - FigureManagerQT, NavigationToolbar2QT, SubplotToolQt, error_msg_qt, - exception_handler) + cursord, _create_qApp, _BackendQT5, TimerQT, MainWindow, FigureManagerQT, + NavigationToolbar2QT, SubplotToolQt, error_msg_qt, exception_handler) from .backend_qt5 import FigureCanvasQT as FigureCanvasQT5 DEBUG = False -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - thisFig = Figure(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasQT(figure) - manager = FigureManagerQT(canvas, num) - return manager - - class FigureCanvasQT(FigureCanvasQT5): def __init__(self, figure): @@ -84,5 +58,6 @@ def wheelEvent(self, event): 'steps = %i ' % (event.delta(), steps)) -FigureCanvas = FigureCanvasQT -FigureManager = FigureManagerQT +@_BackendQT5.export +class _BackendQT4(_BackendQT5): + FigureCanvas = FigureCanvasQT diff --git a/lib/matplotlib/backends/backend_qt4agg.py b/lib/matplotlib/backends/backend_qt4agg.py index 2ca9c3a0c02b..b6fd21fc388d 100644 --- a/lib/matplotlib/backends/backend_qt4agg.py +++ b/lib/matplotlib/backends/backend_qt4agg.py @@ -6,33 +6,12 @@ import six -import matplotlib -from matplotlib.figure import Figure - from .backend_agg import FigureCanvasAgg from .backend_qt4 import ( - QtCore, FigureCanvasQT, FigureManagerQT, NavigationToolbar2QT, - backend_version, draw_if_interactive, show) + QtCore, _BackendQT4, FigureCanvasQT, FigureManagerQT, NavigationToolbar2QT) from .backend_qt5agg import FigureCanvasQTAggBase -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasQTAgg(figure) - return FigureManagerQT(canvas, num) - - class FigureCanvasQTAgg(FigureCanvasQTAggBase, FigureCanvasQT): """ The canvas the figure renders into. Calls the draw and print fig @@ -46,5 +25,6 @@ class FigureCanvasQTAgg(FigureCanvasQTAggBase, FigureCanvasQT): """ -FigureCanvas = FigureCanvasQTAgg -FigureManager = FigureManagerQT +@_BackendQT4.export +class _BackendQT4Agg(_BackendQT4): + FigureCanvas = FigureCanvasQTAgg diff --git a/lib/matplotlib/backends/backend_qt5.py b/lib/matplotlib/backends/backend_qt5.py index e9b069ffc28a..e3a9a77019b0 100644 --- a/lib/matplotlib/backends/backend_qt5.py +++ b/lib/matplotlib/backends/backend_qt5.py @@ -10,22 +10,16 @@ import matplotlib -from matplotlib.backend_bases import FigureManagerBase -from matplotlib.backend_bases import FigureCanvasBase -from matplotlib.backend_bases import NavigationToolbar2 - -from matplotlib.backend_bases import cursors -from matplotlib.backend_bases import TimerBase -from matplotlib.backend_bases import ShowBase - from matplotlib._pylab_helpers import Gcf -from matplotlib.figure import Figure - +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2, + TimerBase, cursors) import matplotlib.backends.qt_editor.figureoptions as figureoptions +from matplotlib.backends.qt_editor.formsubplottool import UiSubplotTool +from matplotlib.figure import Figure from .qt_compat import (QtCore, QtGui, QtWidgets, _getSaveFileName, __version__, is_pyqt5) -from matplotlib.backends.qt_editor.formsubplottool import UiSubplotTool backend_version = __version__ @@ -98,15 +92,6 @@ } -def draw_if_interactive(): - """ - Is called after every pylab drawing command - """ - if matplotlib.is_interactive(): - figManager = Gcf.get_active() - if figManager is not None: - figManager.canvas.draw_idle() - # make place holder qApp = None @@ -147,34 +132,6 @@ def _create_qApp(): pass -class Show(ShowBase): - def mainloop(self): - # allow KeyboardInterrupt exceptions to close the plot window. - signal.signal(signal.SIGINT, signal.SIG_DFL) - global qApp - qApp.exec_() - - -show = Show() - - -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - thisFig = Figure(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasQT(figure) - manager = FigureManagerQT(canvas, num) - return manager - - class TimerQT(TimerBase): ''' Subclass of :class:`backend_bases.TimerBase` that uses Qt timer events. @@ -826,5 +783,19 @@ def exception_handler(type, value, tb): if len(msg): error_msg_qt(msg) -FigureCanvas = FigureCanvasQT -FigureManager = FigureManagerQT + +@_Backend.export +class _BackendQT5(_Backend): + FigureCanvas = FigureCanvasQT + FigureManager = FigureManagerQT + + @staticmethod + def trigger_manager_draw(manager): + manager.canvas.draw_idle() + + @staticmethod + def mainloop(): + # allow KeyboardInterrupt exceptions to close the plot window. + signal.signal(signal.SIGINT, signal.SIG_DFL) + global qApp + qApp.exec_() diff --git a/lib/matplotlib/backends/backend_qt5agg.py b/lib/matplotlib/backends/backend_qt5agg.py index 50d05a4f5c24..ec9a70c5bb68 100644 --- a/lib/matplotlib/backends/backend_qt5agg.py +++ b/lib/matplotlib/backends/backend_qt5agg.py @@ -10,33 +10,15 @@ import traceback from matplotlib import cbook -from matplotlib.figure import Figure from matplotlib.transforms import Bbox from .backend_agg import FigureCanvasAgg from .backend_qt5 import ( - QtCore, QtGui, FigureCanvasQT, FigureManagerQT, NavigationToolbar2QT, - backend_version, draw_if_interactive, show) + QtCore, QtGui, _BackendQT5, FigureCanvasQT, FigureManagerQT, + NavigationToolbar2QT, backend_version) from .qt_compat import QT_API -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasQTAgg(figure) - return FigureManagerQT(canvas, num) - - class FigureCanvasQTAggBase(FigureCanvasAgg): """ The canvas the figure renders into. Calls the draw and print fig @@ -190,5 +172,6 @@ def __init__(self, figure): self.figure.dpi = self._dpi_ratio * self.figure._original_dpi -FigureCanvas = FigureCanvasQTAgg -FigureManager = FigureManagerQT +@_BackendQT5.export +class _BackendQT5Agg(_BackendQT5): + FigureCanvas = FigureCanvasQTAgg diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 0d1506c68dfc..b42f9f1f312f 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -15,8 +15,9 @@ import uuid from matplotlib import verbose, __version__, rcParams -from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ - FigureManagerBase, FigureCanvasBase +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase, + RendererBase) from matplotlib.backends.backend_mixed import MixedModeRenderer from matplotlib.cbook import is_writable_file_like, maxdict from matplotlib.colors import rgb2hex @@ -1254,21 +1255,6 @@ class FigureManagerSVG(FigureManagerBase): pass -def new_figure_manager(num, *args, **kwargs): - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasSVG(figure) - manager = FigureManagerSVG(canvas, num) - return manager - - svgProlog = """\ = 8.5: - # put a mpl icon on the window rather than the default tk icon. Tkinter - # doesn't allow colour icons on linux systems, but tk >=8.5 has a iconphoto - # command which we call directly. Source: - # http://mail.python.org/pipermail/tkinter-discuss/2006-November/000954.html - icon_fname = os.path.join(rcParams['datapath'], 'images', 'matplotlib.ppm') - icon_img = Tk.PhotoImage(file=icon_fname) - try: - window.tk.call('wm', 'iconphoto', window._w, icon_img) - except (SystemExit, KeyboardInterrupt): - # re-raise exit type Exceptions - raise - except: - # log the failure, but carry on - verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1]) - - canvas = FigureCanvasTkAgg(figure, master=window) - figManager = FigureManagerTkAgg(canvas, num, window) - if matplotlib.is_interactive(): - figManager.show() - canvas.draw_idle() - return figManager - class TimerTk(TimerBase): ''' @@ -1095,5 +1042,46 @@ def destroy(self, *args, **kwargs): backend_tools.ToolSetCursor = SetCursorTk backend_tools.ToolRubberband = RubberbandTk Toolbar = ToolbarTk -FigureCanvas = FigureCanvasTkAgg -FigureManager = FigureManagerTkAgg + + +@_Backend.export +class _BackendTkAgg(_Backend): + FigureCanvas = FigureCanvasTkAgg + FigureManager = FigureManagerTkAgg + + @staticmethod + def new_figure_manager_given_figure(num, figure): + """ + Create a new figure manager instance for the given figure. + """ + _focus = windowing.FocusManager() + window = Tk.Tk(className="matplotlib") + window.withdraw() + + # Put a mpl icon on the window rather than the default tk icon. + # Tkinter doesn't allow colour icons on linux systems, but tk>=8.5 has + # a iconphoto command which we call directly. Source: + # http://mail.python.org/pipermail/tkinter-discuss/2006-November/000954.html + icon_fname = os.path.join( + rcParams['datapath'], 'images', 'matplotlib.ppm') + icon_img = Tk.PhotoImage(file=icon_fname) + try: + window.tk.call('wm', 'foobar', window._w, icon_img) + except Exception as exc: + # log the failure (due e.g. to Tk version), but carry on + verbose.report('Could not load matplotlib icon: %s' % exc) + + canvas = FigureCanvasTkAgg(figure, master=window) + manager = FigureManagerTkAgg(canvas, num, window) + if matplotlib.is_interactive(): + manager.show() + canvas.draw_idle() + return manager + + @staticmethod + def trigger_manager_draw(manager): + manager.show() + + @staticmethod + def mainloop(): + Tk.mainloop() diff --git a/lib/matplotlib/backends/backend_webagg.py b/lib/matplotlib/backends/backend_webagg.py index efb92c17c9a0..e39bf2cb2bab 100644 --- a/lib/matplotlib/backends/backend_webagg.py +++ b/lib/matplotlib/backends/backend_webagg.py @@ -37,60 +37,13 @@ import matplotlib from matplotlib import rcParams from matplotlib import backend_bases +from matplotlib.backend_bases import _Backend from matplotlib.figure import Figure from matplotlib._pylab_helpers import Gcf from . import backend_webagg_core as core from .backend_webagg_core import TimerTornado -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasWebAgg(figure) - manager = core.FigureManagerWebAgg(canvas, num) - return manager - - -def draw_if_interactive(): - """ - Is called after every pylab drawing command - """ - if matplotlib.is_interactive(): - figManager = Gcf.get_active() - if figManager is not None: - figManager.canvas.draw_idle() - - -class Show(backend_bases.ShowBase): - def mainloop(self): - WebAggApplication.initialize() - - url = "http://127.0.0.1:{port}{prefix}".format( - port=WebAggApplication.port, - prefix=WebAggApplication.url_prefix) - - if rcParams['webagg.open_in_browser']: - import webbrowser - webbrowser.open(url) - else: - print("To view figure, visit {0}".format(url)) - - WebAggApplication.start() - - -show = Show().mainloop - - class ServerThread(threading.Thread): def run(self): tornado.ioloop.IOLoop.instance().start() @@ -381,4 +334,27 @@ def ipython_inline_display(figure): port=WebAggApplication.port).decode('utf-8') -FigureCanvas = FigureCanvasWebAgg +@_Backend.export +class _BackendWebAgg(_Backend): + FigureCanvas = FigureCanvasWebAgg + FigureManager = FigureManagerWebAgg + + @staticmethod + def trigger_manager_draw(manager): + manager.canvas.draw_idle() + + @staticmethod + def show(): + WebAggApplication.initialize() + + url = "http://127.0.0.1:{port}{prefix}".format( + port=WebAggApplication.port, + prefix=WebAggApplication.url_prefix) + + if rcParams['webagg.open_in_browser']: + import webbrowser + webbrowser.open(url) + else: + print("To view figure, visit {0}".format(url)) + + WebAggApplication.start() diff --git a/lib/matplotlib/backends/backend_webagg_core.py b/lib/matplotlib/backends/backend_webagg_core.py index 132361afc95f..917f4a437364 100644 --- a/lib/matplotlib/backends/backend_webagg_core.py +++ b/lib/matplotlib/backends/backend_webagg_core.py @@ -26,29 +26,12 @@ import datetime from matplotlib.backends import backend_agg +from matplotlib.backend_bases import _Backend from matplotlib.figure import Figure from matplotlib import backend_bases from matplotlib import _png -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - FigureClass = kwargs.pop('FigureClass', Figure) - thisFig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, thisFig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - canvas = FigureCanvasWebAggCore(figure) - manager = FigureManagerWebAgg(canvas, num) - return manager - - # http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes _SHIFT_LUT = {59: ':', 61: '+', @@ -566,3 +549,9 @@ def _timer_set_interval(self): if self._timer is not None: self._timer_stop() self._timer_start() + + +@_Backend.export +class _BackendWebAggCoreAgg(_Backend): + FigureCanvas = FigureCanvasWebAggCore + FigureManager = FigureManagerWebAgg diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index 6e9c0c916d4a..f6bc3d23a50f 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -28,11 +28,9 @@ import numpy as np import matplotlib -from matplotlib import cbook -from matplotlib.backend_bases import (RendererBase, GraphicsContextBase, - FigureCanvasBase, FigureManagerBase, NavigationToolbar2, - cursors, TimerBase) -from matplotlib.backend_bases import ShowBase +from matplotlib.backend_bases import ( + _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase, + NavigationToolbar2, RendererBase, TimerBase, cursors) from matplotlib.backend_bases import _has_pil from matplotlib._pylab_helpers import Gcf @@ -1166,72 +1164,6 @@ def _onEnter(self, evt): ######################################################################## -def _create_wx_app(): - """ - Creates a wx.App instance if it has not been created sofar. - """ - wxapp = wx.GetApp() - if wxapp is None: - wxapp = wx.App(False) - wxapp.SetExitOnFrameDelete(True) - # retain a reference to the app object so it does not get garbage - # collected and cause segmentation faults - _create_wx_app.theWxApp = wxapp - - -def draw_if_interactive(): - """ - This should be overridden in a windowing environment if drawing - should be done in interactive python mode - """ - DEBUG_MSG("draw_if_interactive()", 1, None) - - if matplotlib.is_interactive(): - - figManager = Gcf.get_active() - if figManager is not None: - figManager.canvas.draw_idle() - - -class Show(ShowBase): - def mainloop(self): - needmain = not wx.App.IsMainLoopRunning() - if needmain: - wxapp = wx.GetApp() - if wxapp is not None: - wxapp.MainLoop() - -show = Show() - - -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - # in order to expose the Figure constructor to the pylab - # interface we need to create the figure here - DEBUG_MSG("new_figure_manager()", 3, None) - _create_wx_app() - - FigureClass = kwargs.pop('FigureClass', Figure) - fig = FigureClass(*args, **kwargs) - return new_figure_manager_given_figure(num, fig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - fig = figure - frame = FigureFrameWx(num, fig) - figmgr = frame.get_figure_manager() - if matplotlib.is_interactive(): - figmgr.frame.Show() - figure.canvas.draw_idle() - - return figmgr - - class FigureFrameWx(wx.Frame): def __init__(self, num, fig): # On non-Windows platform, explicitly set the position - fix @@ -1886,6 +1818,43 @@ def OnPrintPage(self, page): # ######################################################################## -FigureCanvas = FigureCanvasWx -FigureManager = FigureManagerWx Toolbar = NavigationToolbar2Wx + + +@_Backend.export +class _BackendWx(_Backend): + FigureCanvas = FigureCanvasWx + FigureManager = FigureManagerWx + _frame_class = FigureFrameWx + + @staticmethod + def trigger_manager_draw(manager): + manager.canvas.draw_idle() + + @classmethod + def new_figure_manager(cls, num, *args, **kwargs): + # Create a wx.App instance if it has not been created sofar. + wxapp = wx.GetApp() + if wxapp is None: + wxapp = wx.App(False) + wxapp.SetExitOnFrameDelete(True) + # Retain a reference to the app object so that it does not get + # garbage collected. + _BackendWx._theWxApp = wxapp + return super(_BackendWx, cls).new_figure_manager(num, *args, **kwargs) + + @classmethod + def new_figure_manager_given_figure(cls, num, figure): + frame = cls._frame_class(num, figure) + figmgr = frame.get_figure_manager() + if matplotlib.is_interactive(): + figmgr.frame.Show() + figure.canvas.draw_idle() + return figmgr + + @staticmethod + def mainloop(): + if not wx.App.IsMainLoopRunning(): + wxapp = wx.GetApp() + if wxapp is not None: + wxapp.MainLoop() diff --git a/lib/matplotlib/backends/backend_wxagg.py b/lib/matplotlib/backends/backend_wxagg.py index 36d10a8a41e6..368115e27646 100644 --- a/lib/matplotlib/backends/backend_wxagg.py +++ b/lib/matplotlib/backends/backend_wxagg.py @@ -10,15 +10,12 @@ from . import wx_compat as wxc from . import backend_wx -from .backend_wx import (FigureManagerWx, FigureCanvasWx, +from .backend_wx import (_BackendWx, FigureManagerWx, FigureCanvasWx, FigureFrameWx, DEBUG_MSG, NavigationToolbar2Wx, Toolbar) import wx -show = backend_wx.Show() - - class FigureFrameWxAgg(FigureFrameWx): def get_canvas(self, fig): return FigureCanvasWxAgg(self, -1, fig) @@ -101,36 +98,8 @@ def get_canvas(self, frame, fig): return FigureCanvasWxAgg(frame, -1, fig) -def new_figure_manager(num, *args, **kwargs): - """ - Create a new figure manager instance - """ - # in order to expose the Figure constructor to the pylab - # interface we need to create the figure here - DEBUG_MSG("new_figure_manager()", 3, None) - backend_wx._create_wx_app() - - FigureClass = kwargs.pop('FigureClass', Figure) - fig = FigureClass(*args, **kwargs) - - return new_figure_manager_given_figure(num, fig) - - -def new_figure_manager_given_figure(num, figure): - """ - Create a new figure manager instance for the given figure. - """ - frame = FigureFrameWxAgg(num, figure) - figmgr = frame.get_figure_manager() - if matplotlib.is_interactive(): - figmgr.frame.Show() - figure.canvas.draw_idle() - return figmgr - - -# # agg/wxPython image conversion functions (wxPython >= 2.8) -# + def _convert_agg_to_wx_image(agg, bbox): """ @@ -193,5 +162,8 @@ def _WX28_clipped_agg_as_bitmap(agg, bbox): return destBmp -FigureCanvas = FigureCanvasWxAgg -FigureManager = FigureManagerWx + +@_BackendWx.export +class _BackendWxAgg(_BackendWx): + FigureCanvas = FigureCanvasWxAgg + _frame_class = FigureFrameWxAgg pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy