Commit d9e417ca authored by Yori 'AGy' Fournier's avatar Yori 'AGy' Fournier
Browse files

Original Commit

parents
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v0.0.0,
#
# @file __init__.py
# @author Yori 'AGy' Fournier
# @licence CC-BY-SA
#
# Import and Configuration file for myplotlib
#
# @section Import
#
# myplotlib is base on matplotlib therefore it requires
# Figure and Axes as main classes and a few further functions.
#
# @section Config
#
# Default value for user parameters
# and configuration for the default plotting
#
# @section Module Import
#
# Import of myplotlib classes and function
#
# @section History
#
# v 0.0.0 - __init__.py file for the myplotlib module
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
import os as os
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 fignum_exists, savefig
from matplotlib.axes import Axes
from matplotlib.figure import Figure
from matplotlib import rcParams
# myplotlib
from myData import MyData
# FORM -----------------------------------------------------------------
INFO = " > info-: "
WARN = " > warn-: "
SEVR = " > sevr-: "
DBUG = " > dbug-: "
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
# myIOs
D_IPATH = '../' # default path to project
# print2file
D_OPATH = 'myplotlib/img/' # default path to ouput
D_OFORMAT = 'png' # default format for ouput
# Debug
D_DEBUG = True # default debug value
# GLOBAL VARIABLE ------------------------------------------------------
G_RAWDATAS = {'current': MyData()} # raw data Object
# PLOTTING CONFIGURATION -----------------------------------------------
rc('font', family='serif')
rc('font', size='22')
rc('text', usetex=True) # need dvipng, ghostscript, and Agg
rc('lines', linewidth=1.5)
rc('lines', markersize=6)
rc('axes', linewidth=1.5)
rc('xtick.major', width=1.5, pad=10., size=10.)
rc('ytick.major', width=1.5, pad=8., size=10.)
rc('xtick.minor', width=1.5, size=5.)
rc('ytick.minor', width=1.5, size=5.)
# FUNCTIONS ------------------------------------------------------------
# MyAxes: Overlay on matplotlib.Axes class
from myAxes import MyAxes
# MyIOs.*: input/output function for testing
from myIOs import readStupidData, readStupidData2
# MyFig: Overlay on matplotlib.Figure class
from myFig import MyFig
# myTool.*: interface functions to use myplotlib interactively
from myTool import myfig, screen, print2file
# MyFig4Test: Overlay of Figure for testing
from myFig4Test import MyFig4Test
# some plotting routine for testing
from myPlot4Test import somePlottingRoutine
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v0.0.0,
#
# @file __main__.py
# @author Yori 'AGy' Fournier
# @licence CC-BY-SA
#
# main program of the module to use in command-line mode.
# for printing usage:
#
# > python myplotlib -h
#
# @section Test
#
# run a few Test to verify integrity of library.
#
# @section Plot
#
# interface to the plot scripts
#
# @section History
#
# v 0.0.0 - __main__.py file for the myplotlib module
# no tests and no plots
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
from __init__ import INFO, SPCE, DBUG
from __init__ import screen, print2file
from __init__ import MyFig, MyFig4Test
from __init__ import readStupidData, readStupidData2, somePlottingRoutine
import sys
import getopt
# LOCAL VARIABLE
run4Plot = False
arg4Plot = ''
run4Test = False
# GET PASSED OPTIONS ---------------------------------------------------
usage = '''
{0}Usage: python mfdPlot [-h]
{1} [-t/--test [all/<num of test>]
{1} [-p/--plot <Name of the Plot>]
{1} [-a/--args <String of the arguments>]
{1} [--debug]
'''.format(INFO, SPCE)
# GET OPT
try:
opts, args = getopt.getopt(
sys.argv[1:], "htp:", ["test=", "plot=", "args=", "debug"])
except getopt.GetoptError:
print(usage)
sys.exit(1)
# CASE OPT
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)
# 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')
# 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')
# Print final status
print
print
print(INFO + 'Status of test series: ' + str(status))
if not status:
print(SPCE + 'Number of Failed Tests: ' + str(len(fail)))
print(SPCE + 'List of Failed Tests: ')
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)
# except:
# print('\n'+SEVR+"There is something wrong with your arguments.")
# print(usage)
# print(INFO+"To start interactively:")
# print(SPCE+">> from mfdPlot import * \n")
else:
print(usage)
# ignore everything in img except .gitignore and the folder itself
*
!.gitignore
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v0.0.0,
#
# @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 myplotlib import SEVR, DBUG
from myplotlib import Axes
from myplotlib import rcParams
# Class MyAxes Overwriting Matplotlib.figure.Axes
class MyAxes(Axes):
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, fig, ratio, frameRect, **kwargs):
self.debug = kwargs.get('debug', 0)
# get the frame allowed
framePosX, framePosY, frameWidth, frameHeight = frameRect
# get the size of the figure
figWidth = fig.get_figwidth()
figHeight = fig.get_figheight()
figDpi = fig.get_dpi()
# get the font size in inches
fontsize = rcParams['font.size'] / figDpi
# the largest width and height allowed in inches
maxWidth = figWidth * frameWidth - 8. * (figDpi / 75.) * fontsize
maxHeight = figHeight * frameHeight - 4. * (figDpi / 75.) * fontsize
# the hypothetical width and height in inches
# for a given aspect ratio
hypoWidth = maxHeight / ratio
hypoHeight = maxWidth * ratio
# if the hypothetical width is larger that the
# maximum allowed width (in inches) then chose
# the hypothetical Height
if (hypoWidth > maxWidth):
height = hypoHeight / figHeight # height in percent
width = maxWidth / figWidth # width in percent
posX = framePosX + 4. * (figDpi / 75.) * fontsize / figWidth # posX
posY = framePosY + 3. * (figDpi / 75.) * fontsize / figHeight # posY
else:
height = maxHeight / figHeight
width = hypoWidth / figWidth
posX = framePosX + (frameWidth - width) / 2.
posY = framePosY + 3. * (figDpi / 75.) * fontsize / figHeight
rect = [posX, posY, width, height]
# parent constructor
Axes.__init__(self, fig, rect, **kwargs)
# PLOTTING -----------------------------------------------------------
# the plotting function (need to be overwrite from child
def plotting(self):
try:
self.plot(self.data['xdata'], self.data['ydata'])
except KeyError:
print(SEVR + 'The formatting of the data was apparently wrong. --> EXIT')
return(False)
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):
print(SEVR + 'The Raw Data could not be formatted --> EXIT')
return(False)
if(self.debug):
print(DBUG + 'I formatted the raw data!\n')
print(DBUG + 'formatted data:\n' + str(self.formattedDatas))
return(True)
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v0.0.0,
#
# @file myData.py
# @author Yori 'AGy' Fournier
# @licence CC-BY-SA
#
# MyData class: Container for the RAWDATA versatil format.
#
# @Class MyData
#
# Consists of two main attributes: name and data
# .name is a string that identifies the Data set
# in the G_RAWDATA dictionary (see __init__.py)
# and a dictionary where the rawdata are stored.
#
# @section History
#
# v 0.0.0 - MyAxes class for the myplotlib module, consists
# of a constructor, a pltting function and
# formatRawData.
#
# ======================================================================
#
class MyData():
def __init__(self):
self.name = 'default'
self.data = None
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
# myplotlib v0.0.0,
#
# @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.
# rawdata: 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: This is done to update the figure
# in case of redraw to make sure that
# the attributes are up-to-date.
# Important for interactive work.
#
# @section History
#
# v 0.0.0 - MyFig class for the myplotlib module.
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
from myplotlib import D_FIGSIZE, D_INPUTARG, D_DEBUG, D_REFORMAT, D_FIGNUM
from myplotlib import DBUG, SEVR, INFO, SPCE, WARN
from myplotlib import G_RAWDATAS
from myplotlib import Figure, MyAxes
# Class MyFig Overwriting Matplotlib.fure.Figure
class MyFig(Figure):
# Set the size of the Figure in inch
# (private variable can not be updated)
FIGSIZE = D_FIGSIZE
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, fignum=D_FIGNUM,
inputarg=D_INPUTARG, reformat=D_REFORMAT,
debug=D_DEBUG, *args, **kwargs):
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 + "Size of the figure: " + str(self.FIGSIZE) + ' [inch] \n')
# PLOT ---------------------------------------------------------------
def plot(self):
try:
self.rawdata = G_RAWDATAS[self.inputArg]
except KeyError:
print(SEVR + "The dataset {dataName} does not exist. --> FALSE".format(dataName=self.inputArg))
return(False)