Source code for evalys.visu.core

# coding: utf-8

import collections

import matplotlib.pyplot
import numpy


[docs]def generate_palette(size): """ Return of discrete palette with the specified number of different colors. """ return list(matplotlib.pyplot.cm.viridis(numpy.linspace(0, 1, size)))
# pylint: disable=bad-whitespace COLORBLIND_FRIENDLY_PALETTE = ( # http://jfly.iam.u-tokyo.ac.jp/color/#pallet '#999999', # grey ( .9, .6, 0), # orange (.35, .7, .9), # sky blue ( 0, .6, .5), # bluish green (.95, .9, .25), # yellow ( 0, .45, .7), # blue ( .8, .4, 0), # vermillion ( .8, .6, .7), # reddish purple ) # pylint: enable=bad-whitespace _LayoutSpec = collections.namedtuple('_LayoutSpec', ('fig', 'spec')) _LayoutSpec.__doc__ += ': Helper object to share the layout specifications' _LayoutSpec.fig.__doc__ = 'Figure to be used by the visualization' _LayoutSpec.spec.__doc__ = 'Root `SubplotSpec` for the visualization'
[docs]class EvalysLayout: """ Base layout to organize visualizations. :ivar fig: The actual figure to draw on. :ivar sps: The `SubplotSpec` defined in the layout. :vartype axes: dict :ivar visualizations: Binding of the visualizations injected into the layout. For each key `spskey` in `self.sps`, `self.visualizations[spskey]` is a list of the visualizations with root `SubplotSpec` `self.sps[spskey]`. :vartype visualizations: dict """ def __init__(self, *, wtitle='Evalys Figure'): self.fig = matplotlib.pyplot.figure() self.sps = {} self.visualizations = {} self.wtitle = wtitle
[docs] def show(self): """ Display the figure window. """ self.fig.show()
[docs] def inject(self, visu_cls, spskey, *args, **kwargs): """ Create a visualization, and bind it to the layout. :param visu_cls: The class of the visualization to create. This should be `Visualization` or one of its subclass. :param spskey: The key identifying the `SubplotSpec` fed to the injected `Visualization` (or a subclass). This key must exist in `self.sps`. :param \*args: The positional arguments to be fed to the constructor of the visualization class. :param \**kwargs: The keyword arguments to be fed to the constructor of the visualization class. :returns: The newly created visualization. :rtype: visu_cls """ lspec = _LayoutSpec(fig=self.fig, spec=self.sps[spskey]) new_visu = visu_cls(lspec, *args, **kwargs) self.visualizations.setdefault(spskey, []).append(new_visu) return new_visu
@property def wtitle(self): """ The title of the window containing the layout. """ return self.fig.canvas.get_window_title() @wtitle.setter def wtitle(self, wtitle): self.fig.canvas.set_window_title(wtitle)
[docs]class SimpleLayout(EvalysLayout): """ Simplest possible layout that uses all available space. """ def __init__(self, *, wtitle='Simple Figure'): super().__init__(wtitle=wtitle) self.sps['all'] = matplotlib.gridspec.GridSpec(nrows=1, ncols=1)[0]
[docs]class Visualization: """ Base class to define visualizations. :ivar _lspec: The specification of the layout for the visualization. :vartype _lspec: _LayoutSpec :ivar _ax: The `Axe` to draw on. :ivar palette: The palette of colors to be used. """ def __init__(self, lspec): self._lspec = lspec self._ax = None self._set_axes() self.palette = generate_palette(8) def _set_axes(self): """ Given the `_LayoutSpec` in `self._lspec`, populate `self._ax`. Note that `self._ax` is set to use all the available space given by `self._lspec`. """ gs = matplotlib.gridspec.GridSpecFromSubplotSpec( nrows=1, ncols=1, subplot_spec=self._lspec.spec ) self._ax = self._lspec.fig.add_subplot(gs[0])
[docs] def build(self, jobset): """ Extract meaningful data from `jobset`, and create the plot. """ raise NotImplementedError()
@property def title(self): """ Title of the visualization. """ return self._ax.get_title() @title.setter def title(self, title): self._ax.set_title(title)