Commit 3c5f7a59 authored by Yori 'AGy' Fournier's avatar Yori 'AGy' Fournier
Browse files

First commit of the dev branch cleaner version of the library. not yet compatible with TITVS

parent 9d297e9e
......@@ -61,6 +61,28 @@
- full user control on IOs and data processing
making it fast and safe
** Conceptual workflow
It is important to understand that myplotlib is a data-oriented
plot library. A class represents a figure and an instance of a class
is a realisation of this class (plot) with a given data set.
This fact is important to understand since pyplot of matplotlib
adopt a different approach. Ideed matplotlib consider an empty
figure as an instance of figure class. So not only the data but
also the aspect of the plot are part of the instance.
We made the choice to disantangle both aspect for more transparency
and a better control on what is plotted. As usual this aproach has
advantage and drawbacks.
The major adavntage is a deep understanding and control on what you
are doing, that is an important aspect for scientists.
The major drawback is a longer (but more awared) process for to
plot. You should know what to plot, and somehow how, before starting.
** Organisation of this document
* Requirements
......@@ -216,7 +238,7 @@ class MyNewAxes(MyAxes):
to test just type:
python -m myplotlib
python2.7 -m myplotlib -t
it will run a test should not show any error.
......@@ -229,3 +251,4 @@ class MyNewAxes(MyAxes):
CLOSED: [2016-02-10 mer. 11:31]
** DONE Make a GIT repo
CLOSED: [2016-12-28 Wed 20:19]
** TODO When saving png or ps add meta data of the class version if exists and version of myplotlib
......@@ -39,10 +39,12 @@ import numpy as np
# matplotlib
from matplotlib.pyplot import figure
from matplotlib.pyplot import rc
from matplotlib.pyplot import show, draw, ion, ioff, clf, close
from matplotlib.pyplot import show, draw, ion, ioff, clf
from matplotlib.pyplot import close as mpclose
from matplotlib.pyplot import fignum_exists, savefig
from matplotlib.axes import Axes
from matplotlib.figure import Figure
from matplotlib import is_interactive
from matplotlib import rcParams
# myplotlib
......@@ -57,24 +59,26 @@ SPCE = " > -----: "
# CONFIGURATION --------------------------------------------------------
# myFig
D_FIGNUM = 0 # default figure number
D_FIGSIZE = (8., 6.) # default figure size
D_REFORMAT = True # default reformat value
D_RAWDATA = MyData() # default raw data
D_INPUTARG = 'current' # default Input argument
D_FIGNUM = 0 # default figure number
D_FIGSIZE = (8., 6.) # default figure size
D_REFORMAT = True # default reformat value
D_FORMATTED = False # default formatted value
D_RAWDATA = MyData() # default raw data
D_INPUTARG = 'current' # default Input argument
# myIOs
D_IPATH = '../' # default path to project
D_IPATH = '../' # default path to project
# print2file
D_OPATH = 'myplotlib/img/' # default path to ouput
D_OFORMAT = 'png' # default format for ouput
D_OPATH = 'myplotlib/img/' # default path to ouput
D_OFORMAT = 'png' # default format for ouput
# Debug
D_DEBUG = True # default debug value
D_DEBUG = True # default debug value
# GLOBAL VARIABLE ------------------------------------------------------
G_RAWDATAS = {'current': MyData()} # raw data Object
G_RAWDATAS = {'current': MyData()} # raw data Object
G_MANAGERS = [] # LIST OF THE ACTUAL MANAGERS
# PLOTTING CONFIGURATION -----------------------------------------------
rc('font', family='serif')
......@@ -99,10 +103,16 @@ from myIOs import readStupidData, readStupidData2
from myFig import MyFig
# myTool.*: interface functions to use myplotlib interactively
from myTool import myfig, screen, print2file
from myTool import createWindow, refreshWindow, closeWindow
from myTool import print2file
# MyFig4Test: Overlay of Figure for testing
from myFig4Test import MyFig4Test
# some plotting routine for testing
from myPlot4Test import somePlottingRoutine
from test import myTest
from test import test1, test2, test3, test4
testList = [test1, test2, test3, test4]
......@@ -32,9 +32,7 @@
#
# IMPORT ---------------------------------------------------------------
from __init__ import INFO, SPCE, DBUG
from __init__ import screen, print2file
from __init__ import MyFig, MyFig4Test
from __init__ import readStupidData, readStupidData2, somePlottingRoutine
from __init__ import myTest, testList
import sys
import getopt
......@@ -43,6 +41,7 @@ import getopt
run4Plot = False
arg4Plot = ''
run4Test = False
debug = False
# GET PASSED OPTIONS ---------------------------------------------------
usage = '''
......@@ -67,170 +66,37 @@ for opt, arg in opts:
if(opt == '-h'):
print(usage)
sys.exit(0)
elif opt in ("-t", "--test"):
run4Test = True
elif opt in ("-p", "--plot"):
run4Plot = True
arg4Plot = str(arg)
elif opt in ("--debug"):
if(run4Test):
print(DBUG +
'{title:{c}^{n}}'
.format(title=' Run for Test ', c='=', n=72))
sys.exit(0)
if(run4Plot):
print(DBUG +
'{title:{c}^{n}}'
.format(title=' Run for Plot ', c='=', n=72))
print(SPCE + ' Arguments: ' + str(arg4Plot))
sys.exit(0)
debug = True
# SECTION: TESTS ------------------------------------------------------
if run4Test:
print(INFO + '{title:{c}^{n}}'.format(title=' Run for Test ', c='=', n=72))
# Status of the tests
status = True
fail = []
print
# TEST 1.0: CREATE A MyFig OBJECT FROM readStupidData
try:
if screen(MyFig, readStupidData(ipath='data1'), fignum=0):
print(INFO + "Test-1.0: pass")
else:
status = False
fail.append('Test-1.0')
except:
status = False
fail.append('Test-1.0')
# TEST 1.1: CREATE A MyFig OBJECT FROM NO DATA should return False
try:
if not screen(MyFig, 'data2', fignum=1):
print(INFO + "Test-1.1: pass")
else:
status = False
fail.append('Test-1.1')
except:
status = False
fail.append('Test-1.1')
# TEST 1.2: UPDATE MyFig (1) WITH ALREADY LOADED DATA: 'data1'
try:
if screen(MyFig, 'data1', fignum=1):
print(INFO + "Test-1.2: pass")
else:
status = False
fail.append('Test-1.2')
except:
status = False
fail.append('Test-1.2')
# TEST 1.3: UPDATE MyFig (0) WITH NEW DATA from readStupidData2
try:
if screen(MyFig, readStupidData2(ipath='data2'), fignum=0):
print(INFO + "Test-1.3: pass")
else:
status = False
fail.append('Test-1.3')
except:
status = False
fail.append('Test-1.3')
# TEST 1.4: UPDATE MyFig (0) WITH A NEW CLASS. Should destroy
# Former figure and create new one.
try:
if screen(MyFig4Test, 'data1', fignum=0):
print(INFO + "Test-1.4: pass")
else:
status = False
fail.append('Test-1.4')
except:
status = False
fail.append('Test-1.4')
# TEST 2.0: print MyFig4Test into test.png
try:
if print2file(MyFig4Test, 'data1', 'test2.0.png'):
print(INFO + "Test-2.0: pass")
else:
status = False
fail.append('Test-2.0')
except:
status = False
fail.append('Test-2.0')
# TEST 2.1: print MyFig4Test into test.png
try:
if print2file(MyFig4Test, 'data1', 'test2.1.eps'):
print(INFO + "Test-2.1: pass")
else:
status = False
fail.append('Test-2.1')
except:
status = False
fail.append('Test-2.1')
# TEST 2.2: print MyFig4Test into test.png
try:
if print2file(MyFig4Test, 'data1', 'test2.2'):
print(INFO + "Test-2.2: pass")
else:
status = False
fail.append('Test-2.2')
except:
status = False
fail.append('Test-2.2')
# TEST 2.3: print MyFig4Test into test.png
try:
if print2file(MyFig4Test, 'data1', 'test2.3', oformat='eps'):
print(INFO + "Test-2.3: pass")
else:
status = False
fail.append('Test-2.3')
except:
status = False
fail.append('Test-2.3')
if debug:
print(DBUG + '{title:{c}^{n}}'.format(title=' Run for Test ', c='=', n=72))
else:
print(INFO + '{title:{c}^{n}}'.format(title=' Run for Test ', c='=', n=72))
# TEST 2.4: print MyFig4Test into test.png
try:
if print2file(MyFig4Test,
'data1',
'test2.4.png',
opath='myplotlib/img/'):
print(INFO + "Test-2.4: pass")
else:
status = False
fail.append('Test-2.4')
except:
status = False
fail.append('Test-2.4')
# TEST 2.5: print MyFig4Test into test.png
try:
if not print2file(MyFig4Test,
'data1',
'test2.5.png',
opath='myplotlib/not-existing-folder/'):
print(INFO + "Test-2.5: pass")
else:
status = False
fail.append('Test-2.5')
except:
status = False
fail.append('Test-2.5')
fail = []
status = True
print(INFO + "TESTS: ")
for test in testList:
print
print
print(INFO + '{title:{c}^{n}}'.format(title=' ' + str(test.__name__) + ' ', c='=', n=72))
status = myTest(test, True, fail, debug) # function, expected, fail, debug
if status: print(INFO + 72 * '-' + " [PASSED]")
# Print final status
print
print
......@@ -241,15 +107,14 @@ if run4Test:
for test in fail:
print(SPCE + '\t- ' + str(test))
# SECTION: PLOTS ------------------------------------------------------
elif run4Plot:
print(INFO + '{title:{c}^{n}}'.format(title=' Run for Plot ', c='=', n=72))
# try:
data = arg4Plot
somePlottingRoutine(data)
# data = arg4Plot
# somePlottingRoutine(data)
# except:
# print('\n'+SEVR+"There is something wrong with your arguments.")
# print(usage)
......
......@@ -44,17 +44,16 @@
#
# @section History
#
# v 0.0.0 - MyFig class for the myplotlib module.
# v 0.0.2 - MyFig class for the myplotlib module.
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
from myplotlib import D_FIGSIZE, D_INPUTARG, D_DEBUG, D_REFORMAT, D_FIGNUM
from myplotlib import D_FIGSIZE, D_INPUTARG, D_DEBUG, D_REFORMAT, D_FIGNUM, D_FORMATTED
from myplotlib import DBUG, SEVR, INFO, SPCE, WARN
from myplotlib import G_RAWDATAS
from myplotlib import Figure, MyAxes
......@@ -66,37 +65,44 @@ class MyFig(Figure):
FIGSIZE = D_FIGSIZE
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, fignum=D_FIGNUM,
inputarg=D_INPUTARG, reformat=D_REFORMAT,
debug=D_DEBUG, *args, **kwargs):
def __init__(self, *args, **kwargs):
self.keywords = {'fignum': D_FIGNUM,
'inputarg': D_INPUTARG,
'reformat': D_REFORMAT,
'debug': D_DEBUG,
'reformatted': D_FORMATTED}
# check keywords
for keyword in self.keywords.keys():
# if already in kwargs
if keyword in kwargs.keys():
# overwrite default value
self.keywords[keyword] = kwargs[keyword]
# suppress keyword from kwargs for Figure.__init__
del kwargs[keyword]
# inputarg, reformat, debug, fignum
kwargs['figsize'] = self.FIGSIZE
# parent constructor
Figure.__init__(self, *args, **kwargs)
# parameters
self.debug = debug # debug Flag
self.fignum = fignum # number of the Figure
self.inputArg = inputarg # input arguments
self.reformat = reformat # re-formatted Flag
self.formatted = False
# DEBUG --------------------------------------------------------------
def printDebug(self):
className = str(self.__class__.__name__)
print('\n' + DBUG + " {0} PARAMETERS: ".format(className))
print(SPCE + " Raw data: " + str(self.inputArg))
print(SPCE + " ID the figure: " + str(self.fignum))
print(SPCE + " Raw data: " + str(self.keywords['inputarg']))
print(SPCE + " ID the figure: " + str(self.keywords['fignum']))
print(SPCE + "Size of the figure: " + str(self.FIGSIZE) + ' [inch] \n')
# PLOT ---------------------------------------------------------------
def plot(self):
try:
self.rawdata = G_RAWDATAS[self.inputArg]
self.rawdata = G_RAWDATAS[self.keywords['inputarg']]
except KeyError:
print(SEVR + "The dataset {dataName} does not exist. --> FALSE".format(dataName=self.inputArg))
print(SEVR + "The dataset {dataName} does not exist. --> FALSE".format(dataName=self.keywords['inputarg']))
return(False)
ratio = 6. / 8. # height/width of the axes (in inch)
......@@ -106,10 +112,10 @@ class MyFig(Figure):
ax = MyAxes(self, ratio, frame)
# reformat the data if needed (default True)
if((self.reformat) or (not self.format)):
if((self.keywords['reformat']) or (not self.keywords['formatted'])):
try:
status = ax.formatRawData(self.rawdata)
self.formatted = True
self.keywords['formatted'] = True
except (TypeError, KeyError):
print(SEVR + 'The formatting of the data was apparently wrong. --> EXIT')
return(False)
......@@ -126,10 +132,10 @@ class MyFig(Figure):
return(True)
# UPDATE -------------------------------------------------------------
def update(self, inputarg=D_INPUTARG,
reformat=D_REFORMAT, debug=D_DEBUG,
*args, **kwargs):
def update(self, **kwargs):
self.debug = debug
self.inputArg = inputarg
self.reformat = reformat
# check keywords
for keyword in self.keywords.keys():
# if already in kwargs overwrite default value
if keyword in kwargs.keys():
self.keywords[keyword] = kwargs[keyword]
......@@ -42,24 +42,17 @@
#
# IMPORT ---------------------------------------------------------------
from myplotlib import D_OPATH, D_OFORMAT
from myplotlib import G_RAWDATAS
from myplotlib import G_RAWDATAS, G_MANAGERS
from myplotlib import INFO, SEVR, WARN, SPCE
from myplotlib import figure, fignum_exists
from myplotlib import draw, clf, close
from myplotlib import ion, ioff
from myplotlib import ion, ioff, is_interactive
# Function wrapping matplotlib.pyplot.figure
#
# usage : fig = myfig(+arguments)
#
def myfig(ClassName, *args, **kwargs):
return(figure(FigureClass=ClassName, *args, **kwargs))
from myplotlib import np
# TOOL FUNCTION FOR READING EXISTING DATA ------------------------------
def setCurrentData(name):
# RQ: grawdatas is a global variable
try:
G_RAWDATAS['current'] = G_RAWDATAS[name]
......@@ -70,68 +63,80 @@ def setCurrentData(name):
return(True)
# PRINT TO SCREEN ------------------------------------------------------
#
# Function which plot a class MyFig on screen
#
# usage : screen(MyFig, +arguments)
#
# fio: function for I/Os
# rdn: existing raw data name
#
#def screen(ClassName, dataIdentifier, ipath=D_IPATH, *args, **kwargs):
def screen(ClassName, inputArg, *args, **kwargs):
debug = kwargs.get('debug', 0)
def refreshWindow(window):
# screen parameters
dpi = 75. # nice for screen (FYI: keep it like that)
window.canvas.figure.clf()
window.canvas.figure.plot()
window.canvas.draw()
# interactive on
ion()
return(True)
def createWindow(fig, *args, **kwargs):
# check if the figure already exists
# interactive off
if is_interactive():
ioff()
# Check the figure number (same as window number)
fignum = kwargs.get('fignum', 0)
if(fignum_exists(fignum)):
# set the current figure
fig = figure(fignum)
# Assume the window does not yet exists
alreadyExists = False
# Verify in G_MANAGERS if the window exists
for window in G_MANAGERS:
# check if class of Figure is the same
if(str(fig.__class__.__name__) == str(ClassName.__name__)):
# clean and update
clf()
fig.update(inputarg=inputArg, *args, **kwargs)
else:
close(fignum)
# create the figure of type ClassName
fig = myfig(ClassName, dpi=dpi,
num=fignum, inputarg=inputArg,
*args, **kwargs )
# if it exists just refresh it (ATTENTION NOT YET WITH ACTUALISATION OF FIG)
if(window.num == fignum):
print(WARN + "The window already exists, I'll just refresh it")
else:
# create the figure of type ClassName
fig = myfig(ClassName, dpi=dpi,
num=fignum, inputarg=inputArg,
*args, **kwargs )
if fig.dpi != 75:
fig.dpi = 75
refreshWindow(window)
win = window
alreadyExists = True
# if it does not exists create the window
if not alreadyExists:
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
from matplotlib.backends.backend_gtkagg import FigureManagerGTKAgg as FigureManager
# ADD Window in the Managers List
print(INFO + "I add the window in G_MANAGERS.")
G_MANAGERS.append(FigureManager(FigureCanvas(fig), fignum))
if fig.dpi != 75:
fig.dpi = 75
# print debug if needed
if(fig.debug or debug):
fig.printDebug()
fig.clf()
fig.plot()
G_MANAGERS[-1].canvas.draw()
G_MANAGERS[-1].show()
# plot the figure on screen
status = fig.plot()
win = G_MANAGERS[-1]
# check status
if(not status):
return(False)
# draw the figure
draw()
return(win)
def closeWindow(num):
# end
return(True)
index = None
try:
index = np.where([(win.num == num) for win in G_MANAGERS])[0][0]
status = True
except:
print(WARN + "The window you want to close does not exists.")
status = False
if index is not None:
G_MANAGERS[index].destroy()
del G_MANAGERS[index]
return(status)
#
......
from myplotlib import readStupidData, readStupidData2
from myplotlib import MyFig
from myplotlib import createWindow, closeWindow, refreshWindow
from myplotlib import SEVR, WARN, DBUG
from myplotlib import G_MANAGERS
# TESTER
def myTest(function, expected, failed, debug):
if debug:
status = function(debug)
if status is not expected:
failed.append(str(function.__name__))
return(False)
else:
return(True)
else:
try:
status = function(debug)
if status is not expected:
failed.append(str(function.__name__))
return(False)
else:
return(True)
except:
print(WARN + str(function.__name__) + " caught exception.")
failed.append(str(function.__name__))