Commit 4426fd36 authored by Yori Fournier's avatar Yori Fournier
Browse files

Merge branch 'on-the-way-to-v3' into 'dev'

On the way to v3

See merge request !25
parents 6adab381 81f0d2e7
......@@ -69,7 +69,7 @@ from .config import rcParams
from .myAxes import MyAxes
# MyFig: Overlay on matplotlib.Figure class
from .myFig import MyFig_base, MyFig
from .myFig import MyFig
# MyFig: Overlay on matplotlib.FigureManager class
if rcParams['backend'] == u'TkAgg':
......@@ -86,7 +86,7 @@ from .mytool import window_exists, getCurrentWindowIDs
from .mytool import print2file, print2screen, printListCurrentWindows
from .mytool import getWindow, getFigOnWindow, drawFigOnWindow, giveDataToWindow
from .mytool import closeWindow, closeAllWindows
from .mytool import FigOneAxes_base, FigOneAxes2D, FigOneAxes3D
from .mytool import FigOneAxes
from .test import myTest
......@@ -94,19 +94,22 @@ from .test import myTest
from .test import test100
from .test import test200, test201, test202
from .test import test300, test301, test302, test303, test304, test305
from .test import test306, test307, test308, test309, test310
from .test import test306, test307, test308, test309, test310, test311
from .test import test312
from .test import test400, test401, test402, test403
from .test import test500, test501, test502, test503, test504
from .test import test505, test506, test507, test508
from .test import test505, test506, test507, test508, test509
from .test import test510, test511
from .test import test600
# the tests to run
testList = [test100,
test201, test202,
test300, test301, test302, test303, test304, test305,
test306, test307, test308, test309, test310,
test306, test307, test308, test309, test310, test311,
test312,
test400, test401, test402,
test503, test506, test500, test507, test501, test502,
test504, test505, test508,
test504, test505, test508, test509, test510, test511,
test600,
]
......@@ -51,11 +51,12 @@ from . import rcParams
# Class MyAxes Overwriting Matplotlib.figure.Axes
class MyAxes(Axes):
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, fig, ratio, frameRect, *args, **kwargs):
self.fig = fig
self.declareKeywords()
rect = self.computeRect(ratio, frameRect, *args, **kwargs)
kwargs.pop('forceRatioOnWidth', None)
......@@ -63,6 +64,9 @@ class MyAxes(Axes):
# parent constructor
Axes.__init__(self, fig, rect, **kwargs)
# set a default name. Should be individualized by instance
self.name='default'
# COMPUTE RECT -------------------------------------------------------
......@@ -75,15 +79,23 @@ class MyAxes(Axes):
# get the frame allowed
framePosX, framePosY, frameWidth, frameHeight = frameRect
# get the size of the figure
figWidth = self.fig.get_figwidth()
figHeight = self.fig.get_figheight()
if(forceRatioOnWidth):
rect = [framePosX, framePosY, frameHeight/ratio, frameHeight]
frameWidth = ratio * figWidth / (frameHeight * figHeight)
elif(forceRatioOnHeight):
rect = [framePosX, framePosY, frameWidth, frameWidth*ratio]
else:
rect = [framePosX, framePosY, frameWidth, frameHeight]
return(rect)
frameHeight = ratio * (frameWidth * figWidth) / figHeight
rect = [framePosX, framePosY, frameWidth, frameHeight]
return(rect)
# DECLARE KEYWORDS -------------------------------------------------
def declareKeywords(self):
self.keywords = {}
# PLOTTING -----------------------------------------------------------
def plotting(self):
return(True)
......@@ -95,3 +107,11 @@ class MyAxes(Axes):
# TESTING THE RAWDATA ------------------------------------------------
def testRawData(self, rawdata):
return(True)
# UPDATE -------------------------------------------------------------
def update(self, **kwargs):
for key in kwargs.keys():
if key in self.keywords.keys():
self.keywords[key] = kwargs[key]
......@@ -74,11 +74,12 @@ from . import D_OFORMAT, D_OPATH
from . import DBUG, SEVR, INFO, SPCE, WARN
from . import G_RAWDATAS
from . import MyData
from . import MyAxes
from . import Figure
# Class MyFig Overwriting Matplotlib.figure.Figure
class MyFig_base(Figure):
class MyFig(Figure):
# Set the size of the Figure in inch
# (private variable can not be updated)
......@@ -96,73 +97,216 @@ class MyFig_base(Figure):
self.debug = kwargs.pop('debug', D_DEBUG)
self.formatted = kwargs.pop('formatted', D_FORMATTED)
# update the keywords with there values
if hasattr(self, "keywords") :
self.update(**kwargs)
# remove key if exists
for keyword in self.keywords.keys() :
kwargs.pop(keyword, None)
else:
self.keywords = {}
# initialise the rawdata
self.rawdata = rawdata
# add figsize in the kwargs for Figure.__init__
kwargs['figsize'] = self.FIGSIZE
# parent constructor
Figure.__init__(self, *args, **kwargs)
Figure.__init__(self, figsize=self.FIGSIZE)
# This is required for the interactive mode
# it ensures that a figure can not be bounded
# to several windows and prevent the loss of canvas.
self.boundedToWin = False
# initialise
self._initialize(*args, **kwargs)
self.set_rawdata(rawdata)
# INITIALIZE -------------------------------------------------------
def _initialize(self, *args, **kwargs):
# add the axes
self.addAxes()
# declare the aliases
self.declareAliases()
# update the attributes and keywords
self.update(**kwargs)
# DEBUG --------------------------------------------------------------
def printDebug(self):
className = str(self.__class__.__name__)
print('\n' + DBUG + " {0} PARAMETERS: ".format(className))
print(SPCE + " Raw data: " + str(self.rawdata))
print(SPCE + " ID the figure: " + str(self.fignum))
print(SPCE + "Size of the figure: " + str(self.FIGSIZE) + ' [inch] \n')
# PLOT ---------------------------------------------------------------
def plot(self):
pass
# UPDATE -------------------------------------------------------------
# UPDATE ----------------------------------------------------------
def update(self, **kwargs):
rest = dict()
# check attributes in keywords
for keyword in kwargs.keys():
# if it is the rawdata use the function
if keyword == 'rawdata':
self.set_rawdata(kwargs['rawdata'])
# if it is an attribute
if keyword in self._attributesToUpdateKeys:
elif keyword in self._attributesToUpdateKeys:
# update value
setattr(self, keyword, kwargs[keyword])
# For each axes update the keywords
for ax in self.get_axes():
# if it is a user keyword
elif keyword in self.keywords.keys():
# update
self.keywords[keyword] = kwargs[keyword]
axkwargs = kwargs.copy() # make a copy of kwargs for this axes
# if it is the rawdata use the function
elif keyword == 'rawdata':
self.set_rawdata(kwargs[keyword])
# Check if a key of kwargs has an alias for this axes
for axk in axkwargs.keys():
if axk in self.aliases.keys():
alax, alkey = self.aliases[axk]
# If an alias is found then update axkwargs
if ax == alax:
axkwargs.update({alkey: kwargs[axk]})
# When eventual alias are added then update
ax.update(**axkwargs)
return(True)
# DECLARE ALIASES -------------------------------------------------
def declareAliases(self):
self.aliases = {}
# ADD AXES ---------------------------------------------------------
def addAxes(self, *arg, **kwargs):
pass
# This overwrites MPL add_axes. It gives a name to the axis added so that it is easier to refer to
def add_axes(self, ax, name) :
if isinstance(name, basestring) and isinstance(ax, MyAxes):
ax.name = name
else:
print(SEVR + " there is an error with the input type of add_axes()")
return False
# test if an axes with that name is already present
for pax in self.get_axes() :
if pax.name == name :
print(SEVR + " an axes with that name is already present")
return False
Figure.add_axes(self, ax)
return True
# GET AXES BY NAME -------------------------------------------------
def getAxesByName(self, name):
for ax in self.get_axes() :
if ax.name == name :
return ax
#if the name is correct we should never get here.
print(SEVR + "The axes name ",name," was not found")
return None
# SET RAW DATA -----------------------------------------------------
def set_rawdata(self, rawdata):
from collections import Iterable
from itertools import repeat
self.formatted = False
status = False
# DEFAULT: one item per axes in figure
if isinstance(rawdata, Iterable):
if len(rawdata) == len(self.get_axes()):
if(self.debug): print(DBUG + "set_rawdata: one item per axes")
self.rawdata = rawdata
status = self.formatRawData()
else:
rest.update({keyword : kwargs[keyword]})
self.rawdata = None
print(SEVR + "rawdata should have the dimention of the number of axes: #axes = " + str(len(self.get_axes())) + "; dim of rawdata = " + str(len(rawdata)))
return(False)
if (self.debug and rest != {}) :
print(DBUG + "These keywords have not been updated: " + str(rest))
# CONVINIENT: one object for all axes
elif isinstance(rawdata, MyData):
if(self.debug): print(DBUG + "set_rawdata: one item for all axes")
self.rawdata = repeat(rawdata) # This is the trick rawdata becomes a generator (so smart)
status = self.formatRawData()
else :
print(SEVR + "set_rawdata: I could not set the rawdata...")
self.rawdata = None
status = False
if not status:
print(SEVR + "set_rawdata: I could not set the rawdata...")
self.rawdata = None
return(status)
# FORMAT RAW DATA --------------------------------------------------
def formatRawData(self):
if self.rawdata is not None:
return(True)
for ax, rawdata in zip(self.get_axes(), self.rawdata):
status = False
if(self.debug):
print(INFO + "Axes: " + str(ax.__class__.__name__) + " with index " + str(self.get_axes().index(ax)) + " formats " + rawdata.name)
status = ax.testRawData(rawdata)
if status :
status = ax.formatRawData(rawdata)
else:
status = ax.testRawData(rawdata)
if status:
try:
status = ax.formatRawData(rawdata)
except:
print(SEVR + "The " + str(ax.__class__.__name__) + " with index " + str(self.get_axes().index(ax)) + " could not format the rawdata.")
return(False)
if not status:
return(False)
if self.formatted is False:
self.formatted = True
return(True)
else:
return(False)
# PLOT -------------------------------------------------------------
def plot(self):
status = True
if(self.debug):
print(DBUG + "currently formatting the data...")
if((self.reformat) or (not self.formatted)):
status = self.formatRawData()
if(not status): return(False)
if(self.debug):
print(DBUG + "currently plotting the axes...")
# For all axes in the figure reformat if needed and plot
for ax in self.get_axes():
# clean the axes
ax.cla()
# plot
plottingStatus = ax.plotting()
status = status and plottingStatus
return(status)
# RESET ------------------------------------------------------------
def reset(self, *args, **kwargs):
self.clf()
self._initialize(*args, **kwargs)
self.plot()
# DEBUG --------------------------------------------------------------
def printDebug(self):
className = str(self.__class__.__name__)
print('\n' + DBUG + " {0} PARAMETERS: ".format(className))
print(SPCE + " Raw data: " + str(self.rawdata))
print(SPCE + " ID the figure: " + str(self.fignum))
print(SPCE + "Size of the figure: " + str(self.FIGSIZE) + ' [inch] \n')
# PRINT 2 FILE -------------------------------------------------------
def print2file(self, filename, *args, **kwargs):
......@@ -193,7 +337,10 @@ class MyFig_base(Figure):
# Plot the figure
if not as_seen:
self.plot()
status = self.plot()
if not status:
print(SEVR + 'Can not plot the figure. sorry --> EXIT')
return(False)
# draw the figure on the new canvas
canvas.draw() # not really needed (savefig does that)
......@@ -240,129 +387,3 @@ class MyFig_base(Figure):
self.canvas = winCanvas
return(True)
# CLASS MyFig ==========================================================
class MyFig(MyFig_base):
# CONSTRUCTOR ------------------------------------------------------
def __init__(self, rawdata, *args, **kwargs):
# define user keywords before
# __init__ to erase them from kwargs
self.declareKeywords()
MyFig_base.__init__(self, rawdata, *args, **kwargs)
self._initialize(*args, **kwargs)
# INITIALIZE -------------------------------------------------------
def _initialize(self, *args, **kwargs):
# update the attributes and keywords
self.update(**kwargs)
# add the axes
self.addAxes()
# need to be done for the first init
self.set_rawdata(self.rawdata) # This function can be overwriten
# DECLARE KEYWORDS -------------------------------------------------
def declareKeywords(self):
pass
# ADD AXES ---------------------------------------------------------
def addAxes(self, *arg, **kwargs):
pass
# SET RAW DATA -----------------------------------------------------
def set_rawdata(self, rawdata):
from collections import Iterable
from itertools import repeat
self.formatted = False
status = False
# DEFAULT: one item per axes in figure
if isinstance(rawdata, Iterable):
if(self.debug): print(DBUG + "set_rawdata: one item per axes")
self.rawdata = rawdata
status = self.formatRawData()
# CONVINIENT: one object for all axes
elif isinstance(rawdata, MyData):
if(self.debug): print(DBUG + "set_rawdata: one item for all axes")
self.rawdata = repeat(rawdata) # This is the trick rawdata becomes a generator (so smart)
status = self.formatRawData()
else :
print(SEVR + "set_rawdata: I could not set the rawdata...")
self.rawdata = ()
status = False
return(status)
# FORMAT RAW DATA --------------------------------------------------
def formatRawData(self):
for ax, rawdata in zip(self.get_axes(), self.rawdata):
status = False
if(self.debug):
print(INFO + "Axes: " + str(ax.__class__.__name__) + " with index " + str(self.get_axes().index(ax)) + " formats " + rawdata.name)
status = ax.testRawData(rawdata)
if status :
status = ax.formatRawData(rawdata)
else:
status = ax.testRawData(rawdata)
if status:
try:
status = ax.formatRawData(rawdata)
except:
print(SEVR + "The " + str(ax.__class__.__name__) + " with index " + str(self.get_axes().index(ax)) + " could not format the rawdata.")
return(False)
if not status:
return(False)
if self.formatted is False:
self.formatted = True
return(True)
# PLOT -------------------------------------------------------------
def plot(self):
status = True
self.update()
if(self.debug):
print(DBUG + "currently formatting the data...")
if((self.reformat) or (not self.formatted)):
status = self.formatRawData()
if(not status): return(False)
if(self.debug):
print(DBUG + "currently plotting the axes...")
# For all axes in the figure reformat if needed and plot
for ax in self.get_axes():
# clean the axes
ax.cla()
# plot
plottingStatus = ax.plotting()
status = status and plottingStatus
return(status)
# RESET ------------------------------------------------------------
def reset(self, *args, **kwargs):
self.clf()
self.declareKeywords()
self._initialize(*args, **kwargs)
self.plot()
......@@ -11,7 +11,6 @@ from .myTool import drawFigOnWindow
from .myTool import closeAllWindows
from .myTool import closeWindow
from .figOneAxes_base import FigOneAxes_base
from .figOneAxes2D import FigOneAxes2D
from .figOneAxes3D import FigOneAxes3D
from .figOneAxes import FigOneAxes
from .axPlot2D import AxPlot2D
from .axPlots2D import AxPlots2D
# 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 AxPlot2D(MyAxes):
# DECLARE KEYWORDS --------------------------------------------------
def declareKeywords(self):
self.keywords = {'xRange': D_XRANGE,
'yRange': D_YRANGE,
'logx': D_LOGX,
'logy': D_LOGY}
return(True)
# PLOTTING -----------------------------------------------------------
# the plotting function (need to be overwrite from child
def plotting(self):
# GET ALL PARAMETERS
xRange = self.keywords.get('xRange')
yRange = self.keywords.get('yRange')
logx = self.keywords.get('logx')
logy = self.keywords.get('logy')
xlabel = self.data.get('xlabel')
ylabel = self.data.get('ylabel')
xdata = self.data.get('xdata')
ydata = self.data.get('ydata')
# CHECK IF THE DATA EXISTS
if (xdata is None):
print(SEVR + "I need axes.data['xdata'] to plot... got None")
return(False)
if (ydata is None):
print(SEVR + "I need axes.data['ydata'] to plot... got None")
return(False)
# TRY TO PLOT
try:
# IF XLIN - YLIN
if (not logx) and (not logy):
self.plot(xdata, ydata)
# XLIN - YLOG
elif (not logx) and logy:
self.semilogy(xdata, ydata)
# XLOG - YLIN
elif (not logy) and logx:
self.semilogx(xdata, ydata)
# XLOG - YLOG
else:
self.loglog(xdata, ydata)
except:
print(SEVR + 'The formatting of the data was apparently wrong. --> EXIT')
return(False)
# SET THE LABELS
if (xlabel): self.set_xlabel(xlabel)
if (ylabel): self.set_ylabel(ylabel)
# SET THE RANGES
if (xRange): self.set_xlim(xRange)
if (yRange): self.set_ylim(yRange)
return(True)
# IMPORT ---------------------------------------------------------------
from .. import SEVR, DBUG, INFO
from .. import MyAxes
from itertools import repeat
D_XRANGE = None
D_YRANGE = None
D_LOGY = False
D_LOGX = False