# ============================================================================
#
# Copyright (C) 2007-2013 Conceptive Engineering bvba. All rights reserved.
# www.conceptive.be / info@conceptive.be
#
# This file is part of the Camelot Library.
#
# This file may be used under the terms of the GNU General Public
# License version 2.0 as published by the Free Software Foundation
# and appearing in the file license.txt included in the packaging of
# this file. Please review this information to ensure GNU
# General Public Licensing requirements will be met.
#
# If you are unsure which license is appropriate for your use, please
# visit www.python-camelot.com or contact info@conceptive.be
#
# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# For use of this library in commercial applications, please contact
# info@conceptive.be
#
# ============================================================================
from camelot.container import Container
[docs]class AxesMethod(object):
"""Helper class to substitute a method on an Axes object and
record its calls"""
def __init__(self, method_name, commands):
"""
:param method_name: the name of the method for which this object is a substitute
:param commands: a list in which to store invocations of the method
"""
self._method_name = method_name
self._commands = commands
def __call__(self, *args, **kwargs):
"""record a call the the substitute method into the commands list"""
self._commands.append( (self._method_name, args, kwargs) )
[docs]class AxesContainer( Container ):
"""A container that is able to generate a plot on a matplotlib axes. Methods
can be called on this class as if it were a matplotlib Axes class. All method
calls will be recorded. Of course the methods won't return matplotlib objects.
The set_auto_legend method can be used to turn legens on without the need for
matplotlib objects.
"""
def __init__(self):
"""
:param legend: True or False, to put a legend on the chart
"""
super(AxesContainer, self).__init__()
# store all the method calls that need to be called on a
# matplotlib axes object in a list
self._commands = list()
self._auto_legend = False
def __getattr__(self, attribute_name):
"""Suppose the caller wants to call a function on a matplotlib
axes object"""
return AxesMethod( attribute_name, self._commands )
[docs] def set_auto_legend(self, auto_legend):
"""Specify if the container should try to put a legend on the
plot.
:param auto_legend: True or False
"""
self._auto_legend = auto_legend
[docs] def plot_on_axes(self, ax):
"""Replay the list of stored commands to the real Axes object"""
for name, args, kwargs in self._commands:
getattr(ax, name)(*args, **kwargs)
if self._auto_legend:
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels)
[docs]class PlotContainer( AxesContainer ):
# this line drives pylint crazy because it need axes to be imported
#__doc__ = axes.Axes.plot.__doc__
def __init__(self, *args, **kwargs):
""":param *args, **kwargs: the arguments to be passed to the matplotlib plot command"""
super(PlotContainer, self).__init__()
self.plot( *args, **kwargs )
[docs]class BarContainer( AxesContainer ):
# this line drives pylint crazy because it need axes to be imported
#__doc__ = axes.Axes.bar.__doc__
def __init__(self, *args, **kwargs):
""":param *args, **kwargs: the arguments to be passed to the matplotlib bar command"""
super(BarContainer, self).__init__()
self.bar( *args, **kwargs )