Base plotting library for stock plotters
xxxxxxxxxx
###############################################################################
# #
# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ #
# Contact: beat.support@idiap.ch #
# #
# This file is part of the beat.examples module of the BEAT platform. #
# #
# Commercial License Usage #
# Licensees holding valid commercial BEAT licenses may use this file in #
# accordance with the terms contained in a written agreement between you #
# and Idiap. For further information contact tto@idiap.ch #
# #
# Alternatively, this file may be used under the terms of the GNU Affero #
# Public License version 3 as published by the Free Software and appearing #
# in the file LICENSE.AGPL included in the packaging of this file. #
# The BEAT platform is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
# or FITNESS FOR A PARTICULAR PURPOSE. #
# #
# You should have received a copy of the GNU Affero Public License along #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/. #
# #
###############################################################################
class Plotter(object):
def setup(self, parameters):
"""Sets up basic parameters taking into consideration user input
You must declare all entries you want to control from your plotter, at
your plotter declaration.
"""
self.xlabel = parameters.get('xlabel', 'X')
self.xaxis_multiplier = parameters.get('xaxis_multiplier', 1.0)
self.xaxis_log = parameters.get('xaxis_log', False)
self.ylabel = parameters.get('ylabel', 'Y')
self.yaxis_multiplier = parameters.get('yaxis_multiplier', 1.0)
self.yaxis_log = parameters.get('yaxis_log', False)
self.title = parameters.get('title', 'Plot')
self.label = parameters.get('legend', '').split('&')
self.label = [k for k in self.label if k]
self.grid = parameters.get('grid', False)
self.content_type = parameters.get('content_type', 'image/png')
self.dpi = parameters.get('dpi', 60)
self.width = parameters.get('width', 400)
self.height = parameters.get('height', 300)
def prepare_canvas(self):
"""Prepares the figure canvas and the axis for plotting
Returns:
fig (matplotlib.pyplot.Figure): The figure canvas to draw on
ax (matplotlib.pyplot.axes): The axis installed on the figure in
which we will plot
"""
# Creates the image to return
from matplotlib.figure import Figure
fig = Figure(
frameon=False,
figsize=(
float(self.width)/self.dpi,
float(self.height)/self.dpi,
),
dpi=self.dpi,
tight_layout=True,
)
ax = fig.add_subplot(111)
return fig, ax
def apply_parameters(self, ax):
"""Applies all base parameters to the axis"""
# Sets plot attributes
ax.set_xlabel(self.xlabel)
ax.set_ylabel(self.ylabel)
ax.set_title(self.title)
ax.grid(self.grid)
if self.xaxis_log: ax.set_xscale('log')
if self.yaxis_log: ax.set_yscale('log')
if any(self.label): ax.legend()
def encode_figure(self, fig):
"""Processes the figure and returns the image to be exported
Returns:
img (str): A binary string containing the image, with the type
defined by the user
"""
# Returns the image
import six
if six.PY2:
output = six.StringIO()
else:
output = six.BytesIO()
if self.content_type in ('image/png', 'image/jpeg'):
from matplotlib.backends.backend_agg import FigureCanvasAgg
canvas = FigureCanvasAgg(fig)
if self.content_type.endswith('png'):
canvas.print_png(output)
else:
canvas.print_jpg(output)
else:
from matplotlib.backends.backend_pdf import FigureCanvasPdf
canvas = FigureCanvasPdf(fig)
canvas.print_figure(output)
return output.getvalue()
The code for this algorithm in Python
The ruler at 80 columns indicate suggested POSIX line breaks (for readability).
The editor will automatically enlarge to accomodate the entirety of your input
Use keyboard shortcuts for search/replace and faster editing. For example, use Ctrl-F (PC) or Cmd-F (Mac) to search through this box
Base plotting library containing common code for executing plots.
You must include this library so that your plotter can become an inherited type of the Plotter declared here:
class Plotter(baselib.Plotter): def __init__(self): super(Plotter, self).__init__() def setup(self, parameters): super(Plotter, self).setup(parameters) # setup other parameters, fix things def process(self, inputs): fig, ax = super(Plotter, self).prepare_canvas() # write here your plotting code super(Plotter, self).apply_parameters(ax) # you may override here plotting parameters applied by the base class return super(Plotter, self).encode_figure(fig)
Your plotter must then be declared as follows (so that all parameters are taken into account):
{ "dataformat": "plot/<format>/1", "language": "python", "uses": { "baselib": "plot/baselib/1", }, "description": "Whatever it should be", "multiple": true, "parameters": { "xlabel": { "default": "X", "type": "string", "description": "The label of the X-axis (horizontal)" }, "ylabel": { "default": "Y", "type": "string", "description": "The label of the Y-axis (vertical)" }, "title": { "default": "Scatter plot", "type": "string", "description": "The title for this plot" }, "xaxis_multiplier": { "default": "1.0", "type": "float64", "description": "The multiplication factor for the X-axis (horizontal)" }, "yaxis_multiplier": { "default": "1.0", "type": "float64", "description": "The multiplication factor for the Y-axis (vertical)" }, "legend": { "default": "", "type": "string", "description": "Short description of the data, to be added to the plot" }, "grid": { "default": false, "type": "bool", "description": "If we should draw grid lines or not for the plot" }, "xaxis_log": { "default": false, "type": "bool", "description": "If X-axis (horizontal) should be in log-scale" }, "yaxis_log": { "default": false, "type": "bool", "description": "If Y-axis (vertical) should be in log-scale" }, "dpi": { "default": 60, "type": "uint16", "description": "Dots-per-inch in raster image formats" }, "width": { "default": 400, "type": "uint16", "description": "Width of the resulting image in pixels" }, "height": { "default": 300, "type": "uint16", "description": "Height of the resulting image in pixels" }, "content_type": { "default": "image/png", "description": "The type of image returned", "type": "string", "choice": [ "image/png", "image/jpeg", "application/pdf" ] } } }