Commit 36ede192 authored by Yori's avatar Yori
Browse files

Merge branch 'dev' into toward-v6

new test suite.
parents f3239319 29a2eb6f
Pipeline #695 failed with stage
in 14 seconds
before_script: before_script:
- python3 --version
- python3 -m pip --version
- python3 -m venv --version
- apt-get update -q -y - apt-get update -q -y
- apt-get install python3 python3-dev python3-tk -q -y - apt-get install python3 python3-dev python3-tk -q -y
- wget https://bootstrap.pypa.io/get-pip.py - python3 -m venv --python=python3.6 mplenv
- python3 get-pip.py - . mplenv/bin/activate
- python3 -m pip --version - pip install matplotlib
- python3 -m pip install --upgrade pip
- python3 -m pip install -U matplotlib
- python3 -m pip install pep8
myplotlib_import_local_latex_tkagg: myplotlib_import_local_latex_tkagg:
script: script:
...@@ -18,30 +18,3 @@ myplotlib_import_local_latex_tkagg: ...@@ -18,30 +18,3 @@ myplotlib_import_local_latex_tkagg:
- python3 -m tests - python3 -m tests
- python3 -m tutorials - python3 -m tutorials
- ./clean_test_folder.sh - ./clean_test_folder.sh
myplotlib_test_mytool:
script:
- git name-rev --name-only HEAD
- ls -l
- cd mpl_toolbox/
- cp ../.configs/tests/config-local.py ../config.py
- python3 -m tests
- python3 -m tutorials
myplotlib_import_network_latex_tkagg:
script:
- git name-rev --name-only HEAD
- ls -l
- cd test/network
- ./setup_test_folder.sh -r latex-tkagg
- python3 test_com_nogl.py
- python3 -m tests
- ./clean_test_folder.sh
myplotlib_test_pep8:
script:
- git name-rev --name-only HEAD
- ls -l
- cd test
- python3 -m comp_pep8
allow_failure: true
from .mpl_Data import MplData from .mpl_data import MplData
from matplotlib import rcParams from matplotlib import rcParams
# FORM ----------------------------------------------------------------- # FORM -----------------------------------------------------------------
...@@ -9,6 +9,8 @@ DBUG = " > dbug-: " ...@@ -9,6 +9,8 @@ DBUG = " > dbug-: "
SPCE = " > -----: " SPCE = " > -----: "
# CONFIGURATION -------------------------------------------------------- # CONFIGURATION --------------------------------------------------------
CONTEXT= 'CLIENT'
# myFig # myFig
D_FIGNUM = 0 # default figure number D_FIGNUM = 0 # default figure number
D_FIGSIZE = (8., 6.) # default figure size D_FIGSIZE = (8., 6.) # default figure size
......
...@@ -333,6 +333,7 @@ class MplClient(): ...@@ -333,6 +333,7 @@ class MplClient():
print(str(formated_data.content)) print(str(formated_data.content))
datas = None datas = None
else: else:
# set the figure data to answerSig.value # set the figure data to answerSig.value
datas = formated_data.content datas = formated_data.content
......
...@@ -170,6 +170,7 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -170,6 +170,7 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
self.reformat = kwargs.pop('reformat', D_REFORMAT) self.reformat = kwargs.pop('reformat', D_REFORMAT)
self.debug = kwargs.pop('debug', D_DEBUG) self.debug = kwargs.pop('debug', D_DEBUG)
self.formatted = kwargs.pop('formatted', D_FORMATTED) self.formatted = kwargs.pop('formatted', D_FORMATTED)
self._tagged_keywords = {}
self.aliases = {} self.aliases = {}
self.FIGSIZE = kwargs.pop('figsize', self.FIGSIZE) self.FIGSIZE = kwargs.pop('figsize', self.FIGSIZE)
...@@ -197,6 +198,9 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -197,6 +198,9 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
# This will throw a pep8 error but its needed to prevent # This will throw a pep8 error but its needed to prevent
# confusion with matplotlib -- need another name # confusion with matplotlib -- need another name
# automatically create keys for the axes keywords to provide a 1 to 1 mapping
self._generate_tagged_keywords()
# declare the aliases # declare the aliases
self.declare_aliases() self.declare_aliases()
...@@ -206,6 +210,8 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -206,6 +210,8 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
# PRIVATE UPDATE --------------------------------------------------- # PRIVATE UPDATE ---------------------------------------------------
def _update(self, **kwargs): def _update(self, **kwargs):
forax = {}
# check attributes in keywords # check attributes in keywords
for keyword in kwargs.keys(): for keyword in kwargs.keys():
...@@ -224,37 +230,62 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -224,37 +230,62 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
# update value # update value
setattr(self, keyword, kwargs[keyword]) setattr(self, keyword, kwargs[keyword])
# For each axes update the keywords # it is a keyword
else:
if keyword in self.aliases.keys():
alias_value = kwargs[keyword]
key_group = self.aliases[keyword]
for key in key_group:
# if the key doe not already exists (case of explicit keyword)
if not forax.get(key, False):
forax.update({key: alias_value})
else:
forax.update({keyword: kwargs[keyword]})
# For each axes collect the keywords
for ax in self.get_axes(): for ax in self.get_axes():
forax = {} ax_specific_keys = {}
for keyword in kwargs.keys(): for keyword in forax.keys():
# ignore figure attributes if keyword in self._tagged_keywords.keys():
if keyword in ['rawdata'] + self._attributes_to_update_keys:
pass
# Check if a key of kwargs has an alias for this axes tag_ax, tag_key = self._tagged_keywords[keyword]
elif keyword in self.aliases.keys():
alax, alkey = self.aliases[keyword]
# If an alias is found then update axkwargs if ax == tag_ax:
if ax == alax: ax_specific_keys.update({tag_key: forax[keyword]})
forax.update(**{alkey: kwargs[keyword]})
# use keyword as it is for the axes
else: else:
forax.update(**{keyword: kwargs[keyword]}) # if the keyword was not yet updated by a specific keyword.
if (not ax_specific_keys.get(keyword, False)) and (keyword in ax.keywords):
ax_specific_keys.update({keyword: forax[keyword]})
# Then eventually all collected Keywords are updated in one go # Then eventually all collected Keywords are updated in one go
if (forax): if (ax_specific_keys):
if self.debug: if self.debug:
print (DBUG + ' fig.update ', ax, 'keywords: ', forax) print (DBUG+' fig.update ', ax, 'keywords: ', ax_specific_keys)
ax.update(**forax) ax.update(**ax_specific_keys)
return(True) return(True)
# GENERATE TAGGED KEYWORDS -----------------------------------------
def _generate_tagged_keywords(self):
""" make the axes keywords accessible in the figure context by inserting
a generated name to _tagged_keywords. An auto-naming scheme is
applied like so:
<axes_name>_<keyword_from_axes_context>"""
for ax in self.axes:
for key,val in ax.keywords.items():
self._tagged_keywords.update({ax.name+"_"+key : (ax , key) })
# GET AXES BY NAME ------------------------------------------------- # GET AXES BY NAME -------------------------------------------------
def get_axes_by_name(self, name): def get_axes_by_name(self, name):
...@@ -275,11 +306,31 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -275,11 +306,31 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
if unknownax == ax : if unknownax == ax :
return ax.name return ax.name
# LIST KEYWORDS AVAILABLE IN THE FIGURE ----------------------------
def list_keywords(self):
""" list all keywords (_tagged_keywords) and aliases in readable form.
use get_state() for info on value."""
for ax in self.get_axes():
print(INFO+'Keywords for axes "{}":'.format(self.get_axes_name(ax)))
for key in ax.keywords:
#~ print(self._tagged_keywords.items())
for tk,axkey in self._tagged_keywords.items():
#~ print(tk,axkey)
if (axkey[1] == key) and (axkey[0] == ax):
print(INFO+' "{}": Access by "{}"'.format(key, tk))
for alias,repace_keys in self.aliases.items():
#~ print(alias,repace_keys)
for rk in repace_keys:
#~ print(rk)
if rk == tk:
print(INFO+' or via figure .alias: "{}"'.format(alias))
# GET AXES --------------------------------------------------------- # GET AXES ---------------------------------------------------------
def get_axes(self): def get_axes(self):
return(self.axes) return(self.axes)
# DEBUG -------------------------------------------------------------- # DEBUG ------------------------------------------------------------
def print_debug(self): def print_debug(self):
class_name = str(self.__class__.__name__) class_name = str(self.__class__.__name__)
print('\n' + DBUG + " {0} PARAMETERS: ".format(class_name)) print('\n' + DBUG + " {0} PARAMETERS: ".format(class_name))
...@@ -296,6 +347,26 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -296,6 +347,26 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
def layout(self): def layout(self):
self.grid.layout() self.grid.layout()
# GET STATE -----------------------------------------------------------
def get_state(self):
""" this function collects the current state of in the figure
by creating a dict that holds all keyword,value pairs
(taking the aliases into account)
Warning: myplotlib allows in a transparent manner to modify
the axes directly. Those changes can not be covert.
"""
state = dict()
# test for double keywords and print a waring
for tagged_key, key_value in self._tagged_keywords.items():
ax, ax_key = key_value
state.update({tagged_key : ax.keywords[ax_key]})
return state
# DEF METHOD (DECORATOR) ------------------------------------------- # DEF METHOD (DECORATOR) -------------------------------------------
def def_method(self, f): def def_method(self, f):
name = f.__name__ name = f.__name__
...@@ -305,6 +376,7 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -305,6 +376,7 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
raise KeyError('Fig has no method called {name}'.format(name=name)) raise KeyError('Fig has no method called {name}'.format(name=name))
return(f) return(f)
# === INTERFACE METHODS ============================================ # === INTERFACE METHODS ============================================
# #
# The interfaces methods are the one that the user supposely # The interfaces methods are the one that the user supposely
...@@ -443,6 +515,16 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -443,6 +515,16 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
""" """
pass pass
# PRINT IN NOTEBOOK ------------------------------------------------
def print_in_notebook(self, **kwargs):
"""Print the rendered figure into the current notebook.
In the server context the MplFig can not be rendered, and therefore,
can not print anything into the notebook.
"""
pass
# PRINT TO FILE ---------------------------------------------------- # PRINT TO FILE ----------------------------------------------------
def print_to_file(self, filename, *args, **kwargs): def print_to_file(self, filename, *args, **kwargs):
"""Print the rendered figure into a file. """Print the rendered figure into a file.
...@@ -469,16 +551,6 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -469,16 +551,6 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
""" """
pass pass
# GET STATE --------------------------------------------------------
def get_state(self):
"""Extract the state of the MplFig used to tests synchronisation.
This method make sens only in the client context, and is therefore
implemented in the ClassFactory.
"""
pass
# RE-SYNC FIGURE --------------------------------------------------- # RE-SYNC FIGURE ---------------------------------------------------
def re_sync_fig(self): def re_sync_fig(self):
"""Re-Synchronise a client figure with the server side. """Re-Synchronise a client figure with the server side.
...@@ -717,20 +789,15 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -717,20 +789,15 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
self._initialize(*args, **kwargs) self._initialize(*args, **kwargs)
self.plot() self.plot()
# DEBUG --------------------------------------------------------------
def print_debug(self):
class_name = str(self.__class__.__name__)
print('\n' + DBUG + " {0} PARAMETERS: ".format(class_name))
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 IN NOTEBOOK -------------------------------------------------- # PRINT IN NOTEBOOK --------------------------------------------------
def print_in_notebook(self, **kwargs):
pass
def _print_in_notebook_local(self, **kwargs): def _print_in_notebook_local(self, **kwargs):
"""Print the rendered figure into the current notebook.
keywords:
- as_seen : [without recalling the MplFig.plot method]
"""
as_seen = kwargs.get('as_seen', False) as_seen = kwargs.get('as_seen', False)
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
...@@ -922,47 +989,6 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()): ...@@ -922,47 +989,6 @@ class MplFig(metaclass=FigureClassFactory, context=CONTEXT.lower()):
'The client is not connected to a server yet.' 'The client is not connected to a server yet.'
'Please use the client to set up a sync conection.') 'Please use the client to set up a sync conection.')
def _get_state_client(self):
""" this function collects the current state of in the figure
by creating a dict that holds all keyword,value pairs
(taking the aliases into account)
Warning: myplotlib allows in a transparent manner to modify
the axes directly. Those changes can not be covert.
"""
state = dict()
# test for double keywords and print a waring
for ax in self.axes:
# find aliases for this specific axes
masks = dict()
for alias in self.aliases.keys():
axes_for_alias, keyword = self.aliases[alias]
if axes_for_alias == ax:
masks.update({keyword: alias})
# collect all keywords of the axes and replace the keys with the
# aliases
ax_keywords = ax.keywords.copy()
for mask in masks:
if mask in ax_keywords:
ax_keywords[masks[mask]] = ax_keywords.pop(mask)
# Test if kewords are already set by an other axes
for key in ax_keywords.keys():
if key in state.keys():
print(
'Warning: The keyword \"',
key,
'\" appears in multiple axes. The Defaults will'
' be overwritten. Prevent this by using aliases')
# update the global keyword index
state.update(ax_keywords)
return state
def _re_sync_fig_client(self): def _re_sync_fig_client(self):
if self.client is not None: if self.client is not None:
......
from .. import D_HIERARCHY #~ from .. import D_HIERARCHY
from .myIOs import readStupidData, readStupidData2 from .myIOs import readStupidData, readStupidData2
if D_HIERARCHY in ('CLIENT', 'client'): #~ if D_HIERARCHY in ('CLIENT', 'client'):
from .axTestClient import AxTestClient #~ from .axTestClient import AxTestClient
from .figTestClient import FigTestClient as FigTest #~ from .figTestClient import FigTestClient as FigTest
# from .tests_client import myTest # from .tests_client import myTest
# from .tests_client import test100 # from .tests_client import test100
# from .tests import myTest # from .tests import myTest
...@@ -12,50 +12,50 @@ if D_HIERARCHY in ('CLIENT', 'client'): ...@@ -12,50 +12,50 @@ if D_HIERARCHY in ('CLIENT', 'client'):
# testList = [test100, # testList = [test100,
# ] # ]
elif D_HIERARCHY in ('SERVER', 'server'): #~ elif D_HIERARCHY in ('SERVER', 'server'):
from .axTestServer import AxTestServer #~ from .axTestServer import AxTestServer
from .figTestServer import FigTestServer as FigTest #~ from .figTestServer import FigTestServer as FigTest
# from .tests_server import myTest # from .tests_server import myTest
# from .tests_server import test100 # from .tests_server import test100
# testList = [test100, # testList = [test100,
# ] # ]
elif D_HIERARCHY in ('local', 'LOCAL'): #~ elif D_HIERARCHY in ('local', 'LOCAL'):
from .axTest1 import AxTest1 from .axTest1 import AxTest1
from .axTest1 import AxTestPlot2D, AxTestPlots2D #~ from .axTest1 import AxTestPlot2D, AxTestPlots2D
from .figTest import FigTest1, FigTest2 from .figTest import FigTest1, FigTest2
from .tests import myTest #~ from .tests import myTest
# import the tests # import the tests
from .tests import test100 #~ from .tests import test100
from .tests import test200, test201, test202, test203, test204 #~ from .tests import test200, test201, test202, test203, test204
from .tests import test300, test301, test302, test303, test304, test305 #~ from .tests import test300, test301, test302, test303, test304, test305
from .tests import test306, test307, test308, test309, test310, test311 #~ from .tests import test306, test307, test308, test309, test310, test311
from .tests import test312 #~ from .tests import test312
from .tests import test400, test401, test402, test403 #~ from .tests import test400, test401, test402, test403
from .tests import test500, test501, test502, test503, test504 #~ from .tests import test500, test501, test502, test503, test504
from .tests import test505, test506, test507, test508, test509 #~ from .tests import test505, test506, test507, test508, test509
from .tests import test510, test511 #~ from .tests import test510, test511
from .tests import test600 #~ from .tests import test600
#~
# the tests to run #~ # the tests to run
testList = [test100, #~ testList = [test100,
test201, test202, test203, test204, #~ test201, test202, test203, test204,
test300, test301, test302, test303, test304, test305, #~ test300, test301, test302, test303, test304, test305,
test306, test307, test308, test309, test310, test311, #~ test306, test307, test308, test309, test310, test311,
test312, #~ test312,
test400, test401, test402, #~ test400, test401, test402,
test503, test506, test500, test507, test501, test502, #~ test503, test506, test500, test507, test501, test502,
test504, test505, test508, test509, test510, test511, #~ test504, test505, test508, test509, test510, test511,
test600, #~ test600,
] #~ ]
#~
# for the demos #~ # for the demos
from ..mytool import print2screen #~ from ..mytool import print2screen
#~
else: #~ else:
#~
raise ImportError #~ raise ImportError
...@@ -98,6 +98,7 @@ class AxTest(MplAxes): ...@@ -98,6 +98,7 @@ class AxTest(MplAxes):
return(True) return(True)
class AxBroken(MplAxes): class AxBroken(MplAxes):
def FormatRawdata(self, rawdata): def FormatRawdata(self, rawdata):
...@@ -106,6 +107,7 @@ class AxBroken(MplAxes): ...@@ -106,6 +107,7 @@ class AxBroken(MplAxes):
def Plottting(self): def Plottting(self):
return(True) return(True)
class AxMinimumImplementation(MplAxes): class AxMinimumImplementation(MplAxes):
def format_rawdata(self, rawdata): def format_rawdata(self, rawdata):
...@@ -114,14 +116,20 @@ class AxMinimumImplementation(MplAxes): ...@@ -114,14 +116,20 @@ class AxMinimumImplementation(MplAxes):
def plotting(self): def plotting(self):
return(True) return(True)
class AxWithKeywords(MplAxes): class AxWithKeywords(MplAxes):
def declare_keywords(self): def declare_keywords(self):
self.keywords = {'x_range': [-1., 1.], self.keywords = {'x_range': [-1., 1.],
'y_range': [-1., 1.]} 'y_range': [-1., 1.],
'title': None}
def format_rawdata(self, rawdata): def format_rawdata(self, rawdata):
return(True) return(True)
def plotting(self): def plotting(self):
title = self.keywords.get('title',None)
if title:
self.set_title(title)
return(True) return(True)
# IMPORT --------------------------------------------------------------- # IMPORT ---------------------------------------------------------------
from myplotlib import MplFig from myplotlib import MplFig
from axes_tests import AxTest from axes_tests import AxTest
from axes_tests import AxWithKeywords
class FigTest(MplFig): class FigTest(MplFig):
...@@ -10,6 +12,7 @@ class FigTest(MplFig): ...@@ -10,6 +12,7 @@ class FigTest(MplFig):
self.add_axes(AxTest(self), "p1") self.add_axes(AxTest(self), "p1")
class EmptyFig(MplFig): class EmptyFig(MplFig):
FIGSIZE = (8., 6.) FIGSIZE = (8., 6.)
...@@ -17,6 +20,7 @@ class EmptyFig(MplFig): ...@@ -17,6 +20,7 @@ class EmptyFig(MplFig):