Commit b0ffb09c authored by Yori's avatar Yori
Browse files

Merge branch 'toward-v6' of gitlab.aip.de:yfournier/myplotlib into _compatible_ppd

parents e703f0c8 efc176f2
Pipeline #670 failed with stage
in 24 minutes and 59 seconds
......@@ -70,6 +70,7 @@ if CONTEXT.lower() in ('client', 'local'):
from matplotlib.pyplot import fignum_exists, savefig
from matplotlib.axes import Axes
from matplotlib.figure import Figure
from matplotlib import rcParams
from matplotlib import is_interactive
from matplotlib import use
......@@ -124,9 +125,11 @@ if CONTEXT.lower() in ('client', 'local'):
_G_WINDOWS = []
print(rcParams['backend'])
# MyWin: Overlay on matplotlib.FigureManager class
if rcParams['backend'] == u'TkAgg':
from .myWin_TkAgg import MyWin_TkAgg as MyWin
from .mpl_win_tkagg import MplWin_TkAgg as MplWin
elif rcParams['backend'] == u'GTKAgg':
from .myWin_GTKAgg import MyWin_GTKAgg as MyWin
elif rcParams['backend'] == u'WXAgg':
......
#!/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 FigureManagerTk
# 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_tkagg import FigureManagerTk, FigureCanvasTkAgg
# Test mpl version:
from matplotlib import __version__ as mplvers
if int(mplvers.replace('.', '')[:3]) < 150:
import six
from six.moves import tkinter as Tk
elif int(mplvers.replace('.', '')[:3]) >= 200:
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 MplWin_TkAgg(FigureManagerTk):
# 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']
fignum_specified_by_user = True
else:
num = 0
fignum_specified_by_user = 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(fignum_specified_by_user):
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.bounded_to_win:
# 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 FigureManagerTk class
# (already wondering if this is not a mistake...)
if(debug):
print(INFO + "Used TkAgg backend")
# Create the master app
window = Tk.Tk()
window.withdraw()
# create the canvas
canvas = FigureCanvasTkAgg(fig, master=window)
# create the Figure manager (what we call window)
FigureManagerTk.__init__(self, canvas, num, window)
# bound the figure to the window
self.canvas.figure.bounded_to_win = 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 _bound_figure(self, fig):
fig.canvas = self.canvas
self.canvas.figure = fig
self.canvas.figure.bounded_to_win = True
self.canvas.figure.fignum = self.num
# UNBOUND ----------------------------------------------------------
def _unbound_figure(self):
self.canvas.figure.bounded_to_win = False
self.canvas.figure.fignum = -1
# SETTERS ----------------------------------------------------------
# SET FIGURE -------------------------------------------------------
def set_figure(self, fig):
# first unbound the former figure
self._unbound_figure()
# if the new figure is already bounded close
# its former container.
if fig.bounded_to_win:
win = _G_WINDOWS[np.where(
[(window.num == fig.fignum) for window in _G_WINDOWS])[0][0]]
win.close()
# bound the new figure
self._bound_figure(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._unbound_figure()
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.
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v3.0.1,
#
# @file myAxes.py
# @author Yori 'AGy' Fournier
# @licence CC-BY-SA
#
# MyAxes class: Overlay of matplotlib Axes class
# It is done such that the user can concentrate on
# the important aspect of the figure and not the
# technical part. It consists of a constructor,
# that requires a Figure, the ratio of the xaxis over
# the yaxis, and the frame in which the figure
# should be plotted.
#
# @Class MyAxes
#
# @Constructor(self, fig, ratio, frame, +user defined kw):
#
# @section Functions
#
# - plotting: this is the overwritten function
# from Axes. It is called by it's
# parent-figure's function .plot()
#
# - formatRawData: it computes out of the rawData
# given as argument some quantities that
# are returned as a dictionary and
# become accessable for plotting.
#
# @section History
#
# v 0.0.0 - MyAxes class for the myplotlib module, consists
# of a constructor, a pltting function and
# formatRawData.
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
from .. import SEVR, DBUG, INFO
from .. import MyAxes
from ..mytool import AxPlot2D, AxPlots2D
D_XRANGE = None
D_YRANGE = None
D_LOGY = False
D_LOGX = False
# Class MyAxes Overwriting Matplotlib.figure.Axes
class AxTest1(MyAxes):
def declareKeywords(self):
self.keywords = {'xRange': D_XRANGE,
'yRange': D_YRANGE}
return(True)
# FORMATTING ---------------------------------------------------------
def formatRawData(self, rawdata):
# give value to data a dict
# with xdata, ydata1, zdata, ydata2 ...
try:
self.data = {'xdata': [rawdata.data[0], rawdata.data[1]],
'ydata': [rawdata.data[2], rawdata.data[3]]}
except(TypeError, KeyError, IndexError):
print(SEVR + 'The Raw Data could not be formatted --> EXIT')
return(False)
if(self.fig.debug):
print(DBUG + 'I formatted the raw data!')
return(True)
# PLOTTING -----------------------------------------------------------
# the plotting function (need to be overwrite from child
def plotting(self):
xRange = self.keywords.get('xRange')
yRange = self.keywords.get('yRange')
try:
self.plot(self.data['xdata'], self.data['ydata'])
except KeyError:
print(SEVR + 'The formatting of the data was apparently wrong. --> EXIT')
return(False)
if (xRange): self.set_xlim(xRange)
if (yRange): self.set_ylim(yRange)
return(True)
# Class MyAxes Overwriting Matplotlib.figure.Axes
class AxTestPlots2D(AxPlots2D):
# FORMATTING ---------------------------------------------------------
def formatRawData(self, rawdata):
# give value to data a dict
# with xdata, ydata1, zdata, ydata2 ...
try:
self.data = {'xdata': [rawdata.data[0], rawdata.data[1]],
'ydatas': ([rawdata.data[2], rawdata.data[3]],
[rawdata.data[3], rawdata.data[2]]),
'xlabel': 'Some X Label',
'ylabel': 'Some Y Label',
'labels': ('curve 1', 'curve 2')}
except(TypeError, KeyError, IndexError):
print(SEVR + 'The Raw Data could not be formatted --> EXIT')
return(False)
if(self.fig.debug):
print(DBUG + 'I formatted the raw data!')
return(True)
# Class MyAxes Overwriting Matplotlib.figure.Axes
class AxTestPlot2D(AxPlot2D):
# FORMATTING ---------------------------------------------------------
def formatRawData(self, rawdata):
# give value to data a dict
# with xdata, ydata1, zdata, ydata2 ...
try:
self.data = {'xdata': [rawdata.data[0], rawdata.data[1]],
'ydata': [rawdata.data[2], rawdata.data[3]],
'xlabel': 'Some X Label',
'ylabel': 'Some Y Label'}
except(TypeError, KeyError, IndexError):
print(SEVR + 'The Raw Data could not be formatted --> EXIT')
return(False)
if(self.fig.debug):
print(DBUG + 'I formatted the raw data!')
return(True)
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v3.0.1,
#
# @file myAxes.py
# @author Yori 'AGy' Fournier
# @licence CC-BY-SA
#
# MyAxes class: Overlay of matplotlib Axes class
# It is done such that the user can concentrate on
# the important aspect of the figure and not the
# technical part. It consists of a constructor,
# that requires a Figure, the ratio of the xaxis over
# the yaxis, and the frame in which the figure
# should be plotted.
#
# @Class MyAxes
#
# @Constructor(self, fig, ratio, frame, +user defined kw):
#
# @section Functions
#
# - plotting: this is the overwritten function
# from Axes. It is called by it's
# parent-figure's function .plot()
#
# - formatRawData: it computes out of the rawData
# given as argument some quantities that
# are returned as a dictionary and
# become accessable for plotting.
#
# @section History
#
# v 0.0.0 - MyAxes class for the myplotlib module, consists
# of a constructor, a pltting function and
# formatRawData.
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
from .. import SEVR, DBUG, INFO
from .. import MyAxes
D_XRANGE = None
D_YRANGE = None
D_LOGY = False
D_LOGX = False
# Class MyAxes Overwriting Matplotlib.figure.Axes
class AxTestClient(MyAxes):
def declareKeywords(self):
self.keywords = {'xRange': D_XRANGE,
'yRange': D_YRANGE}
return(True)
# PLOTTING -----------------------------------------------------------
# the plotting function (need to be overwrite from child
def plotting(self):
xRange = self.keywords.get('xRange')
yRange = self.keywords.get('yRange')
try:
self.plot(self.data['xdata'], self.data['ydata'])
except KeyError:
print(SEVR + 'The formatting of the data was apparently wrong. --> EXIT')
return(False)
if (xRange): self.set_xlim(xRange)
if (yRange): self.set_ylim(yRange)
return(True)
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v3.0.1,
#
# @file myAxes.py
# @author Yori 'AGy' Fournier
# @licence CC-BY-SA
#
# MyAxes class: Overlay of matplotlib Axes class
# It is done such that the user can concentrate on
# the important aspect of the figure and not the
# technical part. It consists of a constructor,
# that requires a Figure, the ratio of the xaxis over
# the yaxis, and the frame in which the figure
# should be plotted.
#
# @Class MyAxes
#
# @Constructor(self, fig, ratio, frame, +user defined kw):
#
# @section Functions
#
# - plotting: this is the overwritten function
# from Axes. It is called by it's
# parent-figure's function .plot()
#
# - formatRawData: it computes out of the rawData
# given as argument some quantities that
# are returned as a dictionary and
# become accessable for plotting.
#
# @section History
#
# v 0.0.0 - MyAxes class for the myplotlib module, consists
# of a constructor, a pltting function and
# formatRawData.
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
from .. import D_HIERARCHY
from .. import SEVR, DBUG, INFO
if D_HIERARCHY in ('SERVER', 'server'):
print(INFO+"Testing the server.")
else:
print(SEVR+"This is atest for the server, the imports are not correct.")
raise ImportError
print(INFO+"Just before Imported my Axes")
from .. import MyAxes
print(INFO+"Imported my Axes")
D_XRANGE = None
D_YRANGE = None
D_LOGY = False
D_LOGX = False
# Class MyAxes Overwriting Matplotlib.figure.Axes
class AxTestServer(MyAxes):
# DECLARE KEYWORDS -------------------------------------------------
def declareKeywords(self):
self.keywords = {'xRange': D_XRANGE,
'yRange': D_YRANGE}
return(True)
# FORMATTING -------------------------------------------------------
def formatRawData(self, rawdata):
# give value to data a dict
# with xdata, ydata1, zdata, ydata2 ...
try:
self.data = {'xdata': [rawdata.data[0], rawdata.data[1]],
'ydata': [rawdata.data[2], rawdata.data[3]]}
except(TypeError, KeyError, IndexError):
print(SEVR + 'The Raw Data could not be formatted --> EXIT')
return(False)
if(self.fig.debug):
print(DBUG + 'I formatted the raw data!')
return(True)
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v3.0.1,
#
# @file myFig.py
# @author Yori 'AGy' Fournier
# @licence CC-BY-SA
#
# MyFig class: Overlay of matplotlib Figure class
# It is done such that the user can concentrate on
# the important aspect of the figure and not the
# technical part.
#
# @Class MyFig
#
# @Constructor
#
# fignum: number of the Figure.
# inputarg: identifier of the raw data in G_RAWDATA.
# reformat: flag for reComputing plotted data
# from rawData.
# debug: flag for debugging, more verbatile.
# (kw)args: user defined arguments and keywords.
#
# @section Functions
#
# - printDebug: print some debug information.
#
# - plot: overlay of Figure.plot() function,
# should be overwrited by the user.
# Consists of
# - creating axes,
# - formating the data,
# - adding the axis to the figure
# - plotting the axis
#
# - update: update the parameters in the
# keywords dictionary.
#
# @section History
#
# v 0.1.1 - MyFig class for the myplotlib module.
#
# v 1.0.0 - Changed rawdata with inputarg to allows any type
# of rawdata, can be an array.
#
# replace the attribute format (reserved word) with