###############################################################################
# -*- python -*-
#
# pylab function implementation
#
# Copyright or (C) or Copr. 2006 INRIA - CIRAD - INRA
#
# File author(s): Thomas Cokelaer <Thomas.Cokelaer@inria.fr>
#
# Distributed under the Cecill-C License.
# See accompanying file LICENSE.txt or copy at
# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
#
# OpenAlea WebSite : http://openalea.gforge.inria.fr
#
###############################################################################
__doc__="""axes decorators from pylab"""
__license__= "Cecill-C"
__revision__=" $Id$ "
#//////////////////////////////////////////////////////////////////////////////
from openalea.core import Node
from openalea.core import (Factory, IFileStr, IInt, IBool, IFloat,
ISequence, IEnumStr, IStr, IDirStr, ITuple3, IDict)
import pylab
from openalea.core.external import add_docstring
from openalea.oapylab import tools
from openalea.oapylab.tools import CustomizeAxes
[docs]
class PyLabLegend(Node, CustomizeAxes):
"""Add a legend to the axe. see pylab.legend for details
:param *shadow*: draw a shadow behind legend.
:param *location*: legend location. See :class:`Locations`
:param *numpoints*: the number of points in the legend for line
:param *markercolor*:
:param *fancybox*: draw a frame with a round fancybox
:param *ncol*: number of columns. default is 1
:param *mode*: if mode is "expand", the legend will be horizontally expanded
:param *title*: the legend title
:param *prop*: connect an optional :class`PyLabFontProperties` object to customise further
.. todo:: *scatterpoints*: integer, *scatteroffsets*: , markerscale*: expand
*bbox_to_anchor* , *bbox_transform*
borderpad, labelspacing, handlelength,andletextpad, borderaxespad, columnspacing
:Example:
.. dataflow:: openalea.pylab.test legend
:width: 40%
**The openalea.pylab.demo.figure dataflow.**
.. plot::
:width: 40%
from openalea.core.alea import *
pm = PackageManager()
run_and_display(('openalea.pylab.test', 'legend'),{},pm=pm )
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
CustomizeAxes.__init__(self)
self.add_input(name='axes')
self.add_input(name="shadow", interface=IBool, value=False)
self.add_input(name="location", interface=IEnumStr(list(tools.locations.keys())), value=0)
self.add_input(name="numpoints", interface=IInt, value=2)
self.add_input(name="markerscale", interface=IFloat(0.1,10,0.1), value=1)
self.add_input(name="fancybox", interface=IBool, value=True)
self.add_input(name="ncol", interface=IInt(1,10), value=1)
self.add_input(name="mode", interface=IEnumStr({'None':'None','Expanded':'exapanded'}), value=None)
self.add_input(name="title", interface=IStr, value=None)
#rodo scatterpoints
#borderpad the fractional whitespace inside the legend border
# labelspacing the vertical space between the legend entries
# handlelength the length of the legend handles
# handletextpad the pad between the legend handle and text
# borderaxespad the pad between the axes and legend border
# columnspacing the spacing between columns
#borderaxespad
self.add_input(name="prop", interface=IDict, value={})
#p = pylab.matplotlib.font_manager.FontProperties(size=26)
self.add_output(name="kwds", interface=IDict, value={})
def __call__(self, inputs):
from pylab import legend
kwds = {}
# pylab options
kwds['loc'] = self.get_input('location')
kwds['numpoints'] = self.get_input('numpoints')
kwds['fancybox'] = self.get_input('fancybox')
kwds['markerscale'] = self.get_input('markerscale')
kwds['shadow'] = self.get_input('shadow')
kwds['ncol'] = self.get_input('ncol')
kwds['mode'] = self.get_input('mode')
kwds['title'] = self.get_input('title')
kwds['prop'] = self.get_input('prop')
axes = self.get_axes()
for axe in axes:
axe.legend(**kwds)
axe.get_figure().canvas.draw()
return self.get_input('axes')
[docs]
class PyLabAxis(Node, CustomizeAxes):
"""axis tuning. See pylab.axis for details
.. warning:: not for production
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>"""
def __init__(self):
Node.__init__(self)
#self.add_input(name="text", interface=IStr)
#self.add_input(name="fontdict", interface=IDict, value=None)
self.add_input(name="fontsize", interface=IFloat, value=12.)
self.add_input(name="alpha", interface=IFloat(0., 1., step=0.1), value=0.5)
self.add_input(name="color", interface=IEnumStr(list(tools.colors.keys())), value='blue')
self.add_input(name='backgroundcolor', interface=IEnumStr(list(tools.colors.keys())), value='white')
self.add_input(name='rotation', interface=IFloat, value='horizontal')
#self.add_input(name="withdash", interface=IBool, value=False)
self.add_input(name="kwargs", interface=IDict, value={})
self.add_input(name="fontproperties", interface=IDict, value={})
self.add_output(name="kwargs", interface=IDict, value=None)
def __call__(self, inputs):
from pylab import text
from matplotlib.font_manager import FontProperties as FP
kwds = {}
#kwds['text'] = self.get_input('text')
kwds['fontsize'] = self.get_input('fontsize')
kwds['alpha'] = self.get_input('alpha')
kwds['color'] = self.get_input('color')
kwds['backgroundcolor'] = self.get_input('backgroundcolor')
kwds['rotation'] = self.get_input('rotation')
kwds['fontproperties'] = FP(**self.get_input('fontproperties'))
for key, value in self.get_input('kwargs').items():
try:
kwds[key] = value
except:
print('key already defined. skip it')
pass
#res = text(0,0, self.get_input('text'), **kwds)
return ( kwds,)
[docs]
class PyLabXLabel(Node, CustomizeAxes):
"""Add a label on the x-axis. See pylab.xlabel for details
:param axes: an optional axes where new data will be plotted.
:param str text:
:param int fontsize: font size (default 12)
:param str verticalalignement: (default is top)
:param str horizontalalignment: (default is center)
:param dict textproperties: output of a :class:`PyLabFontProperties` Node
:param dict kwargs: any other key/value pair
:return: the current axes
:Example:
.. dataflow:: openalea.pylab.test xylabels
:width: 40%
**The openalea.pylab.test.title dataflow.** Add a title to an existing
axes.
.. plot::
:width: 40%
from openalea.core.alea import *
pm = PackageManager()
run_and_display(('openalea.pylab.test', 'xylabels'),{},pm=pm)
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
CustomizeAxes.__init__(self)
self.add_input(name="axes")
self.add_input(name="text", interface=IStr, value=None)
self.add_input(name="fontsize", interface=IFloat, value=12.)
self.add_input(name="labelpad", interface=IInt, value=None)
self.add_input(name="verticalalignment", interface=IEnumStr(list(tools.verticalalignment.keys())),
value='top')
self.add_input(name="horizontalalignment", interface=IEnumStr(list(tools.horizontalalignment.keys())),
value='center')
self.add_input(name="text properties", interface=IDict, value={})
self.add_input(name='kwargs', interface=IDict, value={})
self.add_output(name="axes")
def __call__(self, inputs):
kwds = {}
for key, value in self.get_input('text properties').items():
kwds[key]=value
for key, value in self.get_input('kwargs').items():
kwds[key] = value
#input text and fontproperties are overwritten
# kwds['fontsize'] = self.get_input('fontsize')
kwds['labelpad'] = self.get_input('labelpad')
kwds['verticalalignment'] = self.get_input('verticalalignment')
kwds['horizontalalignment'] = self.get_input('horizontalalignment')
axes = self.get_axes()
for axe in axes:
axe.set_xlabel(self.get_input('text'), **kwds)
axe.get_figure().canvas.draw()
return axes
[docs]
class PyLabYLabel(Node, CustomizeAxes):
"""Add a label on the x-axis. See pylab.xlabel for details
:param text:
:param fontsize:
:param verticalalignement:
:param horizontalalignment:
:param text properties: output of a :class:`TextProperties` Node
:Example: See :class:`~openalea.pylab_decorators_wralea.py_pylab.PyLabXLabel`
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
CustomizeAxes.__init__(self)
self.add_input(name="axes")
self.add_input(name="text", interface=IStr, value=None)
self.add_input(name="fontsize", interface=IFloat, value=12.)
self.add_input(name="labelpad", interface=IInt, value=None)
self.add_input(name="verticalalignment", interface=IEnumStr(list(tools.verticalalignment.keys())),
value='center')
self.add_input(name="horizontalalignment", interface=IEnumStr(list(tools.horizontalalignment.keys())),
value='right')
self.add_input(name="text properties", interface=IDict, value={})
self.add_input(name='kwargs', interface=IDict, value={'rotation':'vertical'})
self.add_output(name="axes")
def __call__(self, inputs):
kwds = {}
for key, value in self.get_input('text properties').items():
print(key, value)
kwds[key]=value
for key, value in self.get_input('kwargs').items():
kwds[key] = value
# kwds['fontsize'] = self.get_input('fontsize')
kwds['labelpad'] = self.get_input('labelpad')
kwds['verticalalignment'] = self.get_input('verticalalignment')
kwds['horizontalalignment'] = self.get_input('horizontalalignment')
axes = self.get_axes()
for axe in axes:
axe.set_ylabel(self.get_input('text'), **kwds)
axe.get_figure().canvas.draw()
return axes
[docs]
class PyLabTitle(Node, CustomizeAxes):
"""Add a title to the current axe. See pylab.title for details
:param axes:
:param str text:
:param int fontsize: (default 12)
:param str color: (default black)
:param dict kwargs: (defaut {})
:Example:
.. dataflow:: openalea.pylab.test title
:width: 40%
**The openalea.pylab.test.title dataflow.** Add a title to an existing
axes.
.. plot::
:width: 40%
from openalea.core.alea import *
pm = PackageManager()
run_and_display(('openalea.pylab.test', 'title'),{},pm=pm)
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
from matplotlib import font_manager
Node.__init__(self)
CustomizeAxes.__init__(self)
self.add_input(name="axes")
self.add_input(name="text", interface=IStr, value=None)
self.add_input(name="fontsize", interface=IFloat, value=12)
self.add_input(name="color", interface=IEnumStr(list(tools.colors.keys())), value='black')
self.add_input(name='kwargs', interface=IDict, value={})
self.add_output(name='axes')
def __call__(self, inputs):
kwds = {}
kwds['fontsize'] = self.get_input('fontsize')
kwds['color'] = self.get_input('color')
for key, value in self.get_input('kwargs').items():
kwds[key]=value
text = self.get_input('text')
axes = self.get_axes()
for axe in axes:
axe.set_title(text, **kwds)
axe.get_figure().canvas.draw()
return self.get_input('axes')
[docs]
class PyLabTextProperties(Node):
"""Create a TextProperties dict. See pylab.Text for details.
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
self.add_input(name='alpha', interface=IFloat(0,1,0.1), value=1)
self.add_input(name='color', interface=IEnumStr(list(tools.colors.keys())), value='k')
self.add_input(name='fontproperties', interface=IDict, value={'family':'sans-serif',
'size':12, 'stretch':'normal', 'style':'normal', 'weight':'normal',
'variant':'normal'})
self.add_input(name='horizontalalignment', interface=IEnumStr(list(tools.horizontalalignment.keys())), value='left')
self.add_input(name='rotation', interface=IFloat(-180,180,10), value=0)
self.add_input(name='verticalalignment', interface=IEnumStr(list(tools.verticalalignment.keys())), value='baseline')
self.add_input(name='kwargs', interface=IDict, value = {
#'agg_filter': None,
# 'animated': False,
# 'axes': None,
# 'clip_box': None,
# 'clip_on': True,
# 'clip_path': None,
# 'contains': None,
# 'figure': None,
# 'gid': None,
# 'path_effects': None,
# 'picker': None,
# 'rasterized': None,
# 'rotation_mode': None,
# 'snap': None,
# 'text': '',
# 'transform': None,
'url': None,
# 'visible': True,
'zorder': 3})
self.add_output(name='kwds', interface=IDict, value={})
def __call__(self,inputs):
kwds = {}
for input in self.input_desc:
if input['name'] != 'kwargs':
kwds[input['name']] = self.get_input(input['name'])
else:
# the kwargs
for k,v in self.get_input('kwargs').items():
kwds[k] = v
# finally clear up the fontproperties dictionary and replace it by an instance of font properties.
from pylab import matplotlib
from matplotlib.font_manager import FontProperties
fp = FontProperties(**kwds['fontproperties'])
kwds['fontproperties'] = fp
#hack for matplotlib <1.0.0
del kwds['agg_filter']
return kwds
[docs]
class PyLabFontProperties(Node):
"""A Font properties selector. See matplotlib.font_manager.FontProperties for details.
.. warning:: not to be used alone. Connect this node to a TextProperties node.
:param str family:
:param str style:
:param str weight:
:param str variant:
:param str stretch:
:param str size:
:param str fname: connect to a file with your fonts
:param dict kwargs: any other key/value pair
:return: a dictionary to be used by a FontProperties instance.
.. seealso:: TextProperties
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
self.add_input(name='family', interface=IEnumStr(list(tools.families.keys())), value='serif')
self.add_input(name='style', interface=IEnumStr(list(tools.styles.keys())), value='normal')
self.add_input(name='variant', interface=IEnumStr(list(tools.variants.keys())), value='normal')
self.add_input(name='weight', interface=IEnumStr(list(tools.weights.keys())), value='normal')
self.add_input(name='stretch', interface=IEnumStr(list(tools.streches.keys())), value='normal')
self.add_input(name='size', interface=IEnumStr(list(tools.sizes.keys())), value='medium')
self.add_input(name='fname', interface=IStr, value=None)
self.add_input(name='kwargs', interface=IDict, value={})
#self.add_input(name='_init', _init=None)
#todo style, variant and strethc do not seem to work
self.add_output(name='kwds', interface=IDict, value={})
def __call__(self,inputs):
kwds = {}
kwds['family'] = self.get_input('family')
kwds['style'] = self.get_input('style')
# !!! size must be translated into number.
from pylab import matplotlib
from matplotlib import font_manager
kwds['size'] = font_manager.font_scalings[self.get_input('size')]
kwds['variant'] = self.get_input('variant')
kwds['weight'] = self.get_input('weight')
kwds['stretch'] = self.get_input('stretch')
for key, value in self.get_input('kwargs').items():
kwds[key] = value
return kwds
[docs]
class PyLabSaveFig(Node):
"""Save the current figure in a file. See pylab.savefig for details.
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
from matplotlib.pyplot import rcParams
Node.__init__(self)
self.add_input(name='axes')
self.add_input(name='fname', interface=IStr, value=None)
self.add_input(name='transparent', interface=IBool, value=False)
self.add_input(name='dpi', interface=IInt(40,200,1), value=rcParams['figure.dpi'])
self.add_input(name='facecolor', interface=IEnumStr(list(tools.colors.keys())), value='white')
self.add_input(name='edgecolor', interface=IEnumStr(list(tools.colors.keys())), value='w')
self.add_input(name='orientation', interface=IEnumStr(list(tools.orientation_fig.keys())), value='portrait')
self.add_input(name='papertype', interface=IEnumStr(list(tools.papertypes.keys())), value=None)
self.add_input(name='format', interface=IEnumStr(list(tools.extensions.keys())), value='png')
self.add_input(name='kwargs', interface=IDict, value={})
def __call__(self, inputs):
from pylab import savefig
kwds = {}
kwds['dpi'] = self.get_input('dpi')
kwds['facecolor']=self.get_input('facecolor')
kwds['edgecolor']= self.get_input('edgecolor')
kwds['orientation']=self.get_input('orientation')
kwds['papertype']=self.get_input('papertype')
kwds['format']=tools.extensions[self.get_input('format')]
kwds['transparent']=self.get_input('transparent')
savefig(self.get_input('fname'), **kwds)
[docs]
class PyLabShow(Node):
"""This node simply calls pylab.show(), which may be useful sometimes.
The input and output connectors are not used by the function itself. There
are present to allow this node to be used in a dataflow. Therefore the
output is simply set to be the input parameter.
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
self.add_input(name='dummy')
self.add_output(name='dummy')
def __call__(self, inputs):
from pylab import show
show()
return self.get_input('dummy')
[docs]
class PyLabColorMap(Node):
"""Plot all colormap
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
self.add_input(name='colormap', interface=IEnumStr(list(tools.cmaps.keys())), value='jet')
self.add_input(name='show', interface=IBool, value=False)
self.add_input(name='showall', interface=IBool, value=False)
self.add_output(name='output')
def __call__(self, inputs):
from numpy import outer, arange, ones
from pylab import figure, axis, imshow, title, show, subplot, text, clf, subplots_adjust
maps = self.get_input('colormap')
a=outer(arange(0,1,0.01),ones(10))
if self.get_input('showall') is True:
figure(figsize=(10,5))
clf()
l = len(tools.cmaps)
subplots_adjust(top=0.9,bottom=0.05,left=0.01,right=0.99)
for index, m in enumerate(tools.cmaps):
#print index
subplot(int(l/2)+l%2+1, 2, index+1)
#print int(l/2)+l%2, 2, (index+1)/2+(index+1)%2+1
axis("off")
imshow(a.transpose(),aspect='auto',cmap=tools.get_cmap(m),origin="lower")
#title(m,rotation=0,fontsize=10)
text(0.5,0.5, m)
show()
elif self.get_input('show') is True:
figure(figsize=(10,5))
clf()
axis("off")
imshow(a.transpose(),aspect='auto',cmap=get_cmap(maps),origin="lower")
title(maps,rotation=0,fontsize=10)
show()
from pylab import get_cmap
res = get_cmap(maps)
return res
[docs]
class PyLabXTicks(Node, CustomizeAxes):
"""Set the tick locations and labels. See pylab.xticks for details.
:param axes: the current axes to manipulate.
:param array locs: (default is empty)
:param array labels: (default is empty)
:param float orientation:
:returns: the current axes
:Example:
.. dataflow:: openalea.pylab.test xyticks
:width: 40%
**The openalea.pylab.test.xyticks dataflow.** play with the ticklabels. Notice
the xlabel at 2.5 and the ylabel orientation.
.. plot::
:width: 40%
from openalea.core.alea import *
pm = PackageManager()
run_and_display(('openalea.pylab.test', 'xyticks'),{},pm=pm)
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
CustomizeAxes.__init__(self)
self.add_input(name='axes')
self.add_input(name='locs', interface=ISequence, value=[])
self.add_input(name='labels', interface=ISequence, value=[])
self.add_input(name='rotation', interface=IFloat, value=0)
self.add_input(name='kwargs(text properties)', interface=IDict, value={})
self.add_output(name='axes')
def __call__(self, inputs):
kwds = {}
for key, value in self.get_input('kwargs(text properties)').items():
kwds[key] = value
kwds['rotation'] = self.get_input('rotation')
axes = self.get_axes()
for axe in axes:
locs = self.get_input('locs')
if len(locs) != 0:
axe.set_xticks(locs)
labels = self.get_input('labels')
if len(labels) != 0:
axe.set_xticklabels(labels, **kwds)
axe.set_yticklabels([x.get_text() for x in axe.get_yticklabels()], **kwds)
axe.get_figure().canvas.draw()
return axes
[docs]
class PyLabTickParams(Node, CustomizeAxes):
"""Tune the ticks on an axis. See pylab.tick_params for details.
:param axes: the axes to tune.
:param str axis: which axis to manipulate ('x', 'y', 'both') (default is 'both')
:param bool reset: set all parameters to defaults
:param str which: apply arguments to major ticks only (default is major)
:param str direction: ['in' | 'out'] Puts ticks inside or outside the axes.
:param int length: Tick length in points
:param int width: Tick width in points
:param int pad: Distance in points between tick and label.
:param labelsize: (default 12)
:param labelcolor: (default black)
:param zorder: (default 0)
:param bool bottom: default True
:param bool top:
:param bool left:
:param bool right:
:param bool labelbottom: (default True)
:param bool labeltop: (default False)
:param bool labelleft: (default True)
:param bool labelright: (default False)
:Example:
.. dataflow:: openalea.pylab.test tickparams
:width: 40%
**The openalea.pylab.demo.polar_demo dataflow.** In order to plot a x/y pair of
vectors into a polar plane, you must use the PyLabAxes node and set the polar to True.
Indeed, there is no mecanism to set the axes to polar after PyLabPlot has been called.
.. plot::
:width: 40%
from openalea.core.alea import *
pm = PackageManager()
run_and_display(('openalea.pylab.test', 'tickparams'),{},pm=pm )
"""
def __init__(self):
self.daxis = {'in':'in', 'out':'out', 'both':'both'}
self.ddirection = {'in':'in', 'out':'out'}
Node.__init__(self)
CustomizeAxes.__init__(self)
self.add_input(name='axes')
self.add_input(name='axis', interface=IEnumStr(list(self.daxis.keys())), value='both')
self.add_input(name='reset', interface=IBool, value=False)
self.add_input(name='direction', interface=IEnumStr(list(self.ddirection.keys())), value='in')
self.add_input(name='length', interface=IInt, value=4)
self.add_input(name='width', interface=IInt, value=1)
self.add_input(name='color', interface=IEnumStr(list(tools.colors.keys())), value='black')
self.add_input(name='pad', interface=IInt, value=1)
self.add_input(name='labelsize', interface=IInt, value=12)
self.add_input(name='labelcolor', interface=IEnumStr(list(tools.colors.keys())), value='black')
self.add_input(name='zorder', interface=IInt, value=0)
self.add_input(name='bottom', interface=IBool, value=False)
self.add_input(name='top', interface=IBool, value=False)
self.add_input(name='left', interface=IBool, value=False)
self.add_input(name='right', interface=IBool, value=False)
self.add_input(name='labelbottom', interface=IBool, value=True)
self.add_input(name='labeltop', interface=IBool, value=False)
self.add_input(name='labelleft', interface=IBool, value=True)
self.add_input(name='labelright', interface=IBool, value=False)
def __call__(self, inputs):
kwds = {}
kwds['axis'] = self.daxis[self.get_input('axis')]
kwds['reset'] = self.get_input('reset')
kwds['direction'] = self.ddirection[self.get_input('direction')]
kwds['length'] = self.get_input('length')
kwds['width'] = self.get_input('width')
kwds['color'] = tools.colors[self.get_input('color')]
kwds['pad'] = self.get_input('pad')
kwds['labelsize'] = self.get_input('labelsize')
kwds['labelcolor'] = tools.colors[self.get_input('labelcolor')]
kwds['zorder'] = self.get_input('zorder')
kwds['bottom'] = self.get_input('bottom')
kwds['top'] = self.get_input('top')
kwds['left'] = self.get_input('left')
kwds['right'] = self.get_input('right')
kwds['labelbottom'] = self.get_input('labelbottom')
kwds['labeltop'] = self.get_input('labeltop')
kwds['labelleft'] = self.get_input('labelleft')
kwds['labelright'] = self.get_input('labelright')
try:
from pylab import tick_params
axes = self.get_axes()
for axe in axes:
axe.tick_params(**kwds)
axe.get_figure().canvas.draw()
return axes
except:
import warnings
warnings.warn('\nWARNING: tickparams not available on your system. Consider installing a maplotlib version>=1')
return self.get_axes()
[docs]
class PyLabYTicks(Node, CustomizeAxes):
"""Set the tick locations and labels. See pylab.xticks for details.
:param axes: the current axes to manipulate.
:param array locs: (default is empty)
:param array labels: (default is empty)
:param float orientation:
:returns: the current axes
:Example: see :class:`~openalea.pylab_decorators_wralea.py_pylab.PyLabXTicks`
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
CustomizeAxes.__init__(self)
self.add_input(name='axes')
self.add_input(name='locs', interface=ISequence, value=[])
self.add_input(name='labels', interface=ISequence, value=[])
self.add_input(name='rotation', interface=IFloat, value=0)
self.add_input(name='kwargs(text properties)', interface=IDict, value={})
self.add_output(name='axes')
def __call__(self, inputs):
kwds = {}
for key, value in self.get_input('kwargs(text properties)').items():
kwds[key] = value
kwds['rotation'] = self.get_input('rotation')
axes = self.get_axes()
for axe in axes:
locs = self.get_input('locs')
if len(locs) != 0:
axe.set_yticks(locs)
labels = self.get_input('labels')
if len(labels) != 0:
axe.set_yticklabels(labels)
axe.set_yticklabels([x.get_text() for x in axe.get_yticklabels()], **kwds)
axe.get_figure().canvas.draw()
return axes
[docs]
class PyLabXLim(Node, CustomizeAxes):
"""VisuAlea version of pylab.xlim
:param axes:
:param xmin:
:param xmax:
:param kwargs:
:return: modified axes
:Example:
.. dataflow:: openalea.pylab.test xylim
:width: 40%
**The openalea.pylab.test.xylim dataflow.** Add a title to an existing
axes.
.. plot::
:width: 40%
from openalea.core.alea import *
pm = PackageManager()
run_and_display(('openalea.pylab.test', 'xylim'),{},pm=pm)
.. note:: xmin must be less than xmax
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
CustomizeAxes.__init__(self)
self.add_input(name='axes')
self.add_input(name='xmin', interface=IFloat, value=0. )
self.add_input(name='xmax', interface=IFloat, value=3. )
self.add_input(name='kwargs', interface=IDict, value={})
self.add_output(name='axes')
def __call__(self, inputs):
kwds = {}
for key, value in self.get_input('kwargs').items():
kwds[key] = value
axes = self.get_axes()
xmin = self.get_input('xmin')
xmax = self.get_input('xmax')
assert xmin<=xmax, 'xmin must be less than xmax'
if xmin != xmax:
for axe in axes:
axe.set_xlim(xmin=xmin, xmax=xmax, **kwds)
#SPHINX HACK
axe.get_figure().canvas.draw()
return axes
[docs]
class PyLabYLim(Node, CustomizeAxes):
"""VisuAlea version of pylab.ylim
:param axes:
:param ymin:
:param ymax:
:param kwargs:
:return: modified axes
.. seealso:: :class:`~openalea.pylab_decorators_wralea.py_pylab.PyLabXLim`
.. note:: ymin must be less than ymax
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
CustomizeAxes.__init__(self)
self.add_input(name='axes')
self.add_input(name='ymin', interface=IFloat, value=None )
self.add_input(name='ymax', interface=IFloat, value=None )
self.add_input(name='kwargs', interface=IDict, value={})
self.add_output(name='axes')
def __call__(self, inputs):
kwds = {}
for key, value in self.get_input('kwargs').items():
kwds[key] = value
axes = self.get_axes()
ymin = self.get_input('ymin')
ymax = self.get_input('ymax')
assert ymin<ymax, 'ymin must be less than ymax'
for axe in axes:
axe.set_ylim(ymin=ymin, ymax=ymax, **kwds)
#SPHINX HACK
axe.get_figure().canvas.draw()
return self.get_input('axes')
[docs]
class PyLabGrid(Node, CustomizeAxes):
"""Add a grid to an axes. See pylab.grid for details
:param axes: an input axes
:param bool b: Set the grid on (default is True)
:param str which: where to set the lines (default is major ticks)
:param str linestyle: style of the lines (default is dotted)
:param str color: color of the lines )(default is black)
:param float linewidth: width of the lines (default is 1)
:param dict kwargs: further properties to fully customize the grid
:returns: the current axes
:Example:
.. dataflow:: openalea.pylab.test grid
:width: 40%
**The openalea.pylab.demo.polar_demo dataflow.** In order to plot a x/y pair of
vectors into a polar plane, you must use the PyLabAxes node and set the polar to True.
Indeed, there is no mecanism to set the axes to polar after PyLabPlot has been called.
.. plot::
:width: 40%
from openalea.core.alea import *
pm = PackageManager()
run_and_display(('openalea.pylab.test', 'grid'),{},pm=pm )
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
CustomizeAxes.__init__(self)
self.add_input(name='axes')
#self.add_input(name='b', interface=IBool, value=True)
self.add_input(name='which', interface=IEnumStr(list(tools.which.keys())), value='major')
self.add_input(name='linestyle', interface=IEnumStr(list(tools.linestyles.keys())), value='dotted')
self.add_input(name='color', interface=IEnumStr(list(tools.colors.keys())), value='black')
self.add_input(name='linewidth', interface=IFloat, value=1.0)
self.add_input(name='kwargs', interface=IDict, value={})
self.add_output(name='axes')
def __call__(self, inputs):
kwds = {}
for key, value in self.get_input('kwargs').items():
kwds[key] = value
kwds['linestyle']=tools.linestyles[self.get_input("linestyle")]
kwds['color']=tools.colors[self.get_input("color")]
kwds['linewidth']=self.get_input("linewidth")
#kwds['b']=self.get_input("b")
kwds['which']=self.get_input("which")
axes = self.get_axes()
for axe in axes:
axe.grid(**kwds)
axe.get_figure().canvas.draw()
return self.get_input('axes')
[docs]
class PyLabOrigin(Node):
"""Set the origin. See pylab.imshow for instance.
.. warning: not yet for production
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
self.add_input(name='origin', interface=IEnumStr(origins), value=None)
self.add_output(name='output', interface=IDict, value={})
def __call__(self, inputs):
kwds = {}
kwds['origin'] = self.get_input('origin')
return (kwds ,)
[docs]
class PyLabAxes(Node):
"""Create an axes. See pylab.axes for details.
This node is useful if you want to create a polar axes.
:param input: an optional input axes
:param bool clean: clear the axe if True (default is True)
:param float left: left boundary limit of the axes (default is 0.12)
:param float bottom: bottom boundary limit of the axes (default is 0.12)
:param float width: width of the axes (default is 0.78)
:param float height: height of the axes (default is 0.78)
:param str axisbg: color of the axes background
:param bool frameon: set the frame on (default is True)
:param bool polar: set the axes in polar mode (default is False)
:param str xscale: set the x axes scale (default is linear)
:param str yscale: set the y axes scale (default is linear)
:param str xticks: set the xticks (default is auto)
:param str xticks: set the yticks (default is auto)
:param dict kwargs: more arguments may be provided as a dictionary
:return: the current axes
:Example:
.. dataflow:: openalea.pylab.demo polar_demo
:width: 40%
**The openalea.pylab.demo.polar_demo dataflow.** In order to plot a x/y pair of
vectors into a polar plane, you must use the PyLabAxes node and set the polar to True.
Indeed, there is no mecanism to set the axes to polar after PyLabPlot has been called.
.. plot::
:width: 40%
from openalea.core.alea import *
pm = PackageManager()
run_and_display(('openalea.pylab.demo', 'polar_demo'),{},pm=pm )
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
#[left, bottom, width, height]
self.add_input(name='input')
self.add_input(name='clear', interface=IBool, value=True)
self.add_input(name='left', interface=IFloat(0, 1, 0.01), value=0.12)
self.add_input(name='bottom', interface=IFloat(0, 1, 0.01), value=0.12)
self.add_input(name='width', interface=IFloat(0, 1, 0.01), value=0.78)
self.add_input(name='height', interface=IFloat(0, 1, 0.01), value=0.78)
self.add_input(name='axisbg', interface=IEnumStr(list(tools.colors.keys())), value='white')
self.add_input(name='frameon', interface=IBool, value=True)
self.add_input(name='polar', interface=IBool, value=False)
self.add_input(name='xscale', interface=IEnumStr(list(tools.scale.keys())), value='linear')
self.add_input(name='yscale', interface=IEnumStr(list(tools.scale.keys())), value='linear')
self.add_input(name='xticks', interface=IEnumStr(list(tools.ticks.keys())), value='auto')
self.add_input(name='yticks', interface=IEnumStr(list(tools.ticks.keys())), value='auto')
self.add_input(name='kwargs', interface=IDict, value={})
self.add_output(name='axes', interface=IDict, value={})
self.axe = None
def __call__(self, inputs):
from pylab import axes, gcf
kwds = {}
position = [self.get_input('left'), self.get_input('bottom'),
self.get_input('width'), self.get_input('height')]
if self.get_input('xticks')=='None':
kwds['xticks'] = []
if self.get_input('yticks')=='None':
kwds['yticks'] = []
input_axes = self.get_input('input')
# case of an empty input, we need to create the axes if it does not exist, or clean the existing one.
if input_axes == None:
#this command return the current axe if it exist otherwise it creates a new one
input_axes = axes(position, polar=self.get_input('polar'))
if self.get_input('clear')==True:
input_axes.clear()
input_axes.set_facecolor(self.get_input('axisbg'))
input_axes.set_frame_on(self.get_input('frameon'))
input_axes.set_xscale(self.get_input('xscale'))
input_axes.set_yscale(self.get_input('yscale'))
f = input_axes.get_figure()
f.canvas.draw()
return input_axes
#else
if type(input_axes)!=list: input_axes = [input_axes]
for axe in input_axes:
axe.set_position(position)
axe.set_facecolor(self.get_input('axisbg'))
axe.set_frame_on(self.get_input('frameon'))
axe.set_xscale(self.get_input('xscale'))
axe.set_yscale(self.get_input('yscale'))
f = gcf()
f.canvas.draw()
return input_axes
[docs]
class PyLabAxesDecorator(Node):
"""Node to connect patches or axes decorators to an axes
:param axes: the axe to complete
:param whatever: a connector to use for connecting other nodes that add patches or
decorators such as title and labels.
:return: the current axes
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
self.add_input(name="axes")
self.add_input(name="whatever", interface=ISequence, value=[])
self.add_output(name="axes")
def __call__(self, inputs):
whatever = self.get_input('whatever')
if type(whatever)!=list:
whatever = [whatever]
import matplotlib
from pylab import gca
for this in whatever:
if this != None:
try:
gca().add_patch(this)
gca().get_figure().canvas.draw()
except:
raise ValueError('an invalid object is connected to AxesDecorator. Only patches and artist object accepted for now.')
return self.get_input("axes")
[docs]
class PyLabBox(Node):
"""See pylab.box for details
.. warning: not yet for production
:param axes: an input pylab.axes
:param on' boolean to turn on or off the box of the current axe
:return: the current axes
.. sectionauthor:: Thomas Cokelaer <Thomas.Cokelaer@sophia.inria.fr>
"""
def __init__(self):
Node.__init__(self)
self.add_input(name='axes')
self.add_input(name='on', interface=IBool, value=True)
self.add_output(name='output')
def __call__(self, inputs):
from pylab import box, gca
box(self.get_input('on'))
gca().get_figure().canvas.draw()
return self.get_input('axes')