Commit c2adda6f authored by Yori Fournier's avatar Yori Fournier
Browse files

Made the AxesClassFactory and modified code such that now it works,

it needs cleaning though and this is not compatible with python3

tests and tuto should pass
parent dc891f51
Pipeline #504 passed with stage
in 6 minutes and 2 seconds
......@@ -5,6 +5,7 @@ D_VERSION='v5'
D_HIERARCHY='LOCAL'
D_HOST='localhost'
D_PORT=50803
CONTEXT=D_HIERARCHY
# FORM -----------------------------------------------------------------
INFO = " > info-: "
......
......@@ -34,7 +34,7 @@
#
# IMPORT ---------------------------------------------------------------
from .config import INFO, WARN, SEVR, DBUG, SPCE
from .config import D_HIERARCHY
from .config import D_HIERARCHY, CONTEXT
import os as os
import numpy as np
......@@ -114,7 +114,8 @@ if D_HIERARCHY in ('CLIENT', 'client', 'LOCAL', 'local'):
if D_HIERARCHY in ('CLIENT', 'client'):
# MplAxes: Overlay on matplotlib.Axes class
from .mpl_axes_client import MplAxesClient as MplAxes
# from .mpl_axes_client import MplAxesClient as MplAxes
from .mpl_axes import MplAxes
from .mpl_grid import Grid, VerticalGrid, HorizontalGrid
......@@ -128,7 +129,8 @@ if D_HIERARCHY in ('CLIENT', 'client'):
elif(D_HIERARCHY in ('SERVER', 'server')):
# MplAxes: Overlay on matplotlib.Axes class
from .mpl_axes_server import MplAxesServer as MplAxes
# from .mpl_axes_server import MplAxesServer as MplAxes
from .mpl_axes import MplAxes
from .mpl_grid import Grid, VerticalGrid, HorizontalGrid
......
......@@ -45,8 +45,11 @@
#
# IMPORT ---------------------------------------------------------------
from . import SEVR, DBUG
from . import Axes
from . import rcParams
from . import CONTEXT
if CONTEXT.lower() != 'server':
from . import Axes
from . import rcParams
_D_FRAME = [0.1, 0.1, 0.8, 0.8]
......@@ -93,26 +96,73 @@ def compute_fit_rect(fig, ratio, frame_rect):
return(rect)
# Class Factory
class AxesClassFactory(type):
# PREPARE METHOD --------------------------------------------------
@classmethod
def __prepare__(mcls, name, bases, **kwargs):
return(type.__prepare__(mcls, name, bases))
# NEW METHOD ------------------------------------------------------
def __new__(mcls, name, bases, attrs, **kwargs):
# context = kwargs.get('context', 'local') # python3
context = attrs.get('__context__', 'local') # python2.7
# Set the contextualized parent_constructor method
parent_constructor = attrs.get('parent_constructor_'+str(context))
if parent_constructor is not None:
parent_constructor.__name__ = 'parent_constructor'
attrs.update({'parent_constructor': parent_constructor})
# Set the contextualized update method
update = attrs.get('update_'+str(context))
if update is not None:
update.__name__ = 'update'
attrs.update({'update': update})
# Contextualize the bases for MplAxes
if context in ('client', 'local'):
if bases == (): # in the case of MplAxes
bases = (Axes,)
elif context == 'server':
if bases == (): # in the case of MplAxes
bases = (object,)
else:
print("{sevr} The context given in the configuration file \
is not correct: should be either local, client or server. \
".format(sevr=SEVR))
raise ImportError
# Actually create the class
axes_class = type.__new__(mcls, name, bases, attrs)
return(axes_class)
# INITIALIZATION METHOD -------------------------------------------
def __init__(cls, name, bases, dct, **kwargs):
super(AxesClassFactory, cls).__init__(name, bases, dct)
# Class MyAxes Overwriting Matplotlib.figure.Axes
class MplAxes(Axes):
class MplAxes():
__metaclass__ = AxesClassFactory
__context__ = CONTEXT.lower()
# --- SHARED METHODS -------------------------------------------------
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, fig, frame=_D_FRAME, *args, **kwargs):
def __init__(self, fig, frame=_D_FRAME, **kwargs):
self.fig = fig
self.declare_keywords()
rect = self.compute_rect(frame, *args, **kwargs)
# clean kwargs
kwargs.pop('ratio', None)
kwargs.pop('force_ratio_on_width', None)
kwargs.pop('force_ratio_on_height', None)
kwargs.pop('fit_in_frame', None)
# parent constructor
Axes.__init__(self, fig, rect, **kwargs)
self.parent_constructor(fig, frame, **kwargs)
# set a default name. Should be individualized by instance
self.name = 'default'
......@@ -157,36 +207,51 @@ class MplAxes(Axes):
def declare_keywords(self):
self.keywords = {}
# TESTING THE RAWDATA ----------------------------------------------
def test_rawdata(self, rawdata):
return(True)
# --- INTERFACE METHODS --------------------------------------------
# PLOTTING ---------------------------------------------------------
def plotting(self):
raise(NotImplementedError, 'You should have overwrite the'
' plotting function.')
return(False)
# UNPACKING --------------------------------------------------------
# def unpack_formatted_data(self, packed_data):
# '''Get a string return it evaluation.
# can be overwritten by user.'''
# return(eval(packed_data))
# PACKING ----------------------------------------------------------
# def pack_formatted_data(self, formatted_data):
# '''Get an object return its representation.
# can be overwritten by user.'''
# return(str(formatted_data))
# FORMATTING -------------------------------------------------------
def format_rawdata(self, rawdata):
raise(NotImplementedError, 'You should have overwritten the '
'format_rawdata method.')
return(False)
return(False)
# --- ABSTRACT METHODS ---------------------------------------------
# TESTING THE RAWDATA ----------------------------------------------
def test_rawdata(self, rawdata):
return(True)
# PARENT CONSTRUCTOR -----------------------------------------------
def parent_constructor(self, fig, rect, **kwargs):
raise(NotImplementedError, 'You should have overwritten the '
'parent_constructor method.')
# UPDATE -----------------------------------------------------------
def update(self, *args, **kwargs):
raise(NotImplementedError, 'You should have overwritten the '
'update method.')
# --- LOCAL/CLIENT CONTEXT METHODS ---------------------------------
def parent_constructor_local(self, fig, frame, **kwargs):
rect = self.compute_rect(frame, **kwargs)
# clean kwargs
kwargs.pop('ratio', None)
kwargs.pop('force_ratio_on_width', None)
kwargs.pop('force_ratio_on_height', None)
kwargs.pop('fit_in_frame', None)
Axes.__init__(self, fig, rect, **kwargs)
def update_local(self, *args, **kwargs):
# Because matplotlib.axes.update expect kwargs and not **kwargs
# ... (stupid!! no, this is just WRONG!!)
......@@ -209,3 +274,16 @@ class MplAxes(Axes):
for (key, value) in kwargs.items():
if key in self.keywords:
self.keywords.update({key: value})
parent_constructor_client = parent_constructor_local
update_client = update_local
# --- SERVER CONTEXT METHODS --------------------------------------
def parent_constructor_server(self, fig, frame, **kwargs):
pass
def update_server(self, *args, **kwargs):
for (key, value) in kwargs.items():
if key in self.keywords:
self.keywords.update({key: value})
#!/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.
#
# v 2.2.3 - Add testRawData function
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
from . import SEVR, DBUG
from . import Axes
from . import rcParams
# Class MyAxes Overwriting Matplotlib.figure.Axes
class MplAxesClient(Axes):
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, fig, ratio, frame_rect, *args, **kwargs):
self.fig = fig
self.declare_keywords()
rect = self.compute_rect(ratio, frame_rect, *args, **kwargs)
kwargs.pop('force_ratioOn_width', None)
kwargs.pop('force_ratioOn_height', None)
# parent constructor
Axes.__init__(self, fig, rect, **kwargs)
# set a default name. Should be individualized by instance
self.name = 'default'
# COMPUTE RECT -------------------------------------------------------
def compute_rect(self, ratio, frame_rect, *args, **kwargs):
# Get the optional keyword
force_ratio_on_width = kwargs.pop('force_ratio_on_width', None)
force_ratio_on_height = kwargs.pop('force_ratio_on_height', None)
# get the frame allowed
frame_pos_x, frame_pos_y, frame_width, frame_height = frame_rect
# get the size of the figure
fig_width = self.fig.get_figwidth()
fig_height = self.fig.get_figheight()
if(force_ratio_on_width):
frame_width = ratio * fig_width / (frame_height * fig_height)
elif(force_ratio_on_height):
frame_height = ratio * (frame_width * fig_width) / fig_height
rect = [frame_pos_x, frame_pos_y, frame_width, frame_height]
return(rect)
# DECLARE KEYWORDS -------------------------------------------------
def declare_keywords(self):
self.keywords = {}
# PLOTTING -----------------------------------------------------------
def plotting(self):
return(True)
# UPDATE -------------------------------------------------------------
def update(self, *args, **kwargs):
# Because matplotlib.axes.update expect kwargs and not **kwargs
if args: # catch matplotlib kwargs
kwargs = args[0]
# kw_for_axes = {key: value for (key, value) in args[0].items() if
# key not in self.keywords} # Not compatible with python2.6
kw_for_axes = {}
for (key, value) in args[0].items():
if key not in self.keywords:
kw_for_axes.update({key: value})
Axes.update(self, kw_for_axes) # update matplotlib.Axes
# myplotlib update
# self.keywords.update({key: value for (key, value) in kwargs.items()
# if key in self.keywords}) # Not compatible with python2.6
for (key, value) in kwargs.items():
if key in self.keywords:
self.keywords.update({key: value})
# -*- 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.
#
# v 2.2.3 - Add testRawData function
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
from . import SEVR, DBUG
# Class MyAxes Overwriting Matplotlib.figure.Axes
class MplAxesServer(object):
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, fig, ratio, frame_rect, *args, **kwargs):
self.fig = fig
self.declare_keywords()
# set a default name. Should be individualized by instance
self.name = 'default'
# DECLARE KEYWORDS -------------------------------------------------
def declare_keywords(self):
self.keywords = {}
# FORMATTING ---------------------------------------------------------
def format_rawdata(self, rawdata):
return(True)
# TESTING THE RAWDATA ------------------------------------------------
def test_rawdata(self, rawdata):
return(True)
# UPDATE -------------------------------------------------------------
def update(self, *args, **kwargs):
# myplotlib update
# self.keywords.update({key: value for (key, value) in kwargs.items()
# if key in self.keywords}) # Not compatible with python2.6
for (key, value) in kwargs.items():
if key in self.keywords:
self.keywords.update({key: value})
......@@ -5,6 +5,7 @@ D_VERSION='v5'
D_HIERARCHY='LOCAL'
D_HOST='localhost'
D_PORT=50803
CONTEXT = D_HIERARCHY
# FORM -----------------------------------------------------------------
INFO = " > info-: "
......
......@@ -11,7 +11,7 @@ class FigTest(MplFig):
ratio = 6. / 8. # height/width of the axes (in inch)
frame1 = [0.1, 0.1, 0.8, 0.8] # part of the fig that is available
self.add_axes(AxTest(self, ratio, frame1), "p1")
self.add_axes(AxTest(self), "p1")
class FigTest2(MplFig): # Fig with two Axes
......@@ -25,8 +25,8 @@ class FigTest2(MplFig): # Fig w
frame1 = [0.1, 0.1, 0.4, 0.8] # part of the fig that is available
frame2 = [0.6, 0.1, 0.4, 0.8] # part of the fig that is available
self.add_axes(AxTest(self, ratio, frame1), "p1")
self.add_axes(AxTest(self, ratio, frame2), "p2")
self.add_axes(AxTest(self), "p1")
self.add_axes(AxTest(self), "p2")
def declare_aliases(self):
......
......@@ -5,6 +5,7 @@ D_VERSION='v5'
D_HIERARCHY='CLIENT'
D_HOST='localhost'
D_PORT=50803
CONTEXT = D_HIERARCHY
# FORM -----------------------------------------------------------------
INFO = " > info-: "
......
......@@ -11,7 +11,7 @@ class FigTest(MplFig):
ratio = 6. / 8. # height/width of the axes (in inch)
frame1 = [0.1, 0.1, 0.8, 0.8] # part of the fig that is available
self.add_axes(AxTest(self, ratio, frame1), "p1")
self.add_axes(AxTest(self), "p1")
class FigTest2(MplFig): # Fig with two Axes
......@@ -25,8 +25,8 @@ class FigTest2(MplFig): # Fig w
frame1 = [0.1, 0.1, 0.4, 0.8] # part of the fig that is available
frame2 = [0.6, 0.1, 0.4, 0.8] # part of the fig that is available
self.add_axes(AxTest(self, ratio, frame1),"p1")
self.add_axes(AxTest(self, ratio, frame2),"p2")
self.add_axes(AxTest(self),"p1")
self.add_axes(AxTest(self),"p2")
def declare_aliases(self):
......
......@@ -5,6 +5,7 @@ D_VERSION='v5'
D_HIERARCHY='SERVER'
D_HOST='localhost'
D_PORT=50803
CONTEXT = D_HIERARCHY
# FORM -----------------------------------------------------------------
INFO = " > info-: "
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment