#!/usr/bin/python # -*- coding: utf-8 -*- # # ================= FILE HEADER ======================================== # # myplotlib v3.0.1, # # @file myWin_TkAgg.py # @author Yori 'AGy' Fournier # @licence CC-BY-SA # # MyWin_TkAgg class: Overlay of matplotlib FigureManagerTkAgg # class. It allows a cleaner and more confortable usage of windows # with the TkAgg Backend. # # @Class MyWin_TkAgg # # @Constructor # # fig: the MyFig object that need to be drawn # show: a flag to show the window just after # creation. (default: True) # fignum: number of both the Window and the Figure. # debug: flag for debugging, more verbatile. # (kw)args: user defined arguments and keywords. # # @section Functions # # - _boundFigure_: bound a figure to the window (priv.) # # - _unboundFigure_: unbound a figure to the window (priv.) # # - set_figure: a clean way of setting a new figure # to the window. # # - refresh: redraw the window # - clean the figure # - plot the figure # - draw the canvas # # - drawFigure: draw a given figure on the window # - set the figure of needed # - refresh # # - close: close the window # # @section History # # v 1.0.1 - MyWin_TkAgg class for the myplotlib module. # # ====================================================================== # # IMPORT --------------------------------------------------------------- from . import INFO, SEVR, WARN, DBUG, SPCE from . import rcParams from . import _G_WINDOWS from . import np # For the backend from matplotlib.backends.backend_macosx import FigureManagerMac, FigureCanvasMac # Test mpl version: from matplotlib import __version__ as mplvers if int(mplvers.replace('.','')[:3]) < 150 : import six from six.moves import tkinter as Tk else : from matplotlib.externals import six from matplotlib.externals.six.moves import tkinter as Tk # Class MyWin Overwriting the disgusting Matplotlib.FigureManager class class MyWin_MacOSx(FigureManagerMac): # CONSTRUCTOR ------------------------------------------------------ def __init__(self, fig, show=True, *args, **kwargs): # set the dpi to 75 (correct value for screen) if(fig.dpi != 75.): fig.dpi = 75. # Get the debug value debug = kwargs.get('debug', False) # Get the user specified ID of the window or set it to 0 if 'fignum' in kwargs.keys(): num = kwargs['fignum'] fignumSpecifiedByUser = True else: num = 0 fignumSpecifiedByUser = False # if ID already used if(num in [(window.num) for window in _G_WINDOWS]): # if user specified fignum then close former window and create new one if(fignumSpecifiedByUser): if(debug): print(DBUG + "The fignum you specified already exists, I'll close the former window") # Close the window with the specified number _G_WINDOWS[np.where([(window.num == num) for window in _G_WINDOWS])[0][0]].close() else: # If user didn't specified a fignum # increase ID until found a free one while(num in [(window.num) for window in _G_WINDOWS]): num = num + 1 # If debug print the ID of the window if(debug): print(DBUG + "You choosed num = " + str(num)) # before creating anything verify that the fig is not already # bounded to another window if fig.boundedToWin: # if it is the case close the bounded window. win = _G_WINDOWS[np.where([(window.num == fig.fignum) for window in _G_WINDOWS])[0][0]] win.close() # Call FigureManagerTkAgg class # (already wondering if this is not a mistake...) if(debug): print(INFO + "Used MacOSx backend") # create the canvas canvas = FigureCanvasMac(fig) # create the Figure manager (what we call window) FigureManagerMac.__init__(self, canvas, num) # bound the figure to the window self.canvas.figure.boundedToWin = True self.canvas.figure.fignum = num # add the window in the global variable _G_WINDOWS # this guarenty that you never loose a window # (see myTool.py getWindow(num)) _G_WINDOWS.append(self) # if show is on, then show the window if show: self.refresh() self.show() # BOUND ------------------------------------------------------------ def _boundFigure_(self, fig): fig.canvas = self.canvas self.canvas.figure = fig self.canvas.figure.boundedToWin = True self.canvas.figure.fignum = self.num # UNBOUND ---------------------------------------------------------- def _unboundFigure_(self): self.canvas.figure.boundedToWin = False self.canvas.figure.fignum = -1 # SETTERS ---------------------------------------------------------- # SET FIGURE ------------------------------------------------------- def set_figure(self, fig): # first unbound the former figure self._unboundFigure_() # if the new figure is already bounded close # its former container. if fig.boundedToWin: win = _G_WINDOWS[np.where([(window.num == fig.fignum) for window in _G_WINDOWS])[0][0]] win.close() # bound the new figure self._boundFigure_(fig) # REFRESH ---------------------------------------------------------- def refresh(self): # in the case the figure got another canvas # rebound the figure. This situation should not happend!! if self.canvas != self.canvas.figure.canvas: print(WARN + "Something weird happend, the canvas of the figure have been changed") self.set_figure(self.canvas.figure) # refresh self.canvas.figure.plot() self.canvas.draw() return(True) # DRAW ------------------------------------------------------------- def drawFigure(self, fig): # if the figure is not the current one if(fig.fignum != self.num): # cleanly set the new figure self.set_figure(fig) # and refresh self.refresh() # CLOSE ------------------------------------------------------------ def close(self): self._unboundFigure_() self.destroy() del _G_WINDOWS[np.where([(window == self) for window in _G_WINDOWS])[0][0]] # remark if you create the window like: # win = MyWin(fig) # then win is still refering the self # and therefore not yet freed # del win would free it entirely.