Source code for tellurium.plotting.engine_mpl
"""
Matplotlib implementation of the plotting engine.
"""
from __future__ import absolute_import, print_function, division
from .engine import PlottingEngine, PlottingFigure, PlottingLayout
import os
import matplotlib.pyplot as plt
from matplotlib import gridspec
from tempfile import mkstemp
# enable fixes for non-IPython environment
IPYTHON = False
if any('IPYTHONDIR' in name for name in os.environ):
IPYTHON = True
[docs]class MatplotlibEngine(PlottingEngine):
""" Matplotlib engine."""
def __init__(self):
super(MatplotlibEngine, self).__init__()
def __str__(self):
return "<MatplotlibEngine>"
[docs] @classmethod
def newFigure(cls, title=None, logX=False, logY=False, layout=None, xtitle=None, ytitle=None):
""" Returns a figure object."""
if layout is None:
layout = PlottingLayout()
fig = MatplotlibFigure(title=title, layout=layout, xtitle=xtitle, ytitle=ytitle, logx=logX, logy=logY)
return fig
[docs]class MatplotlibFigure(PlottingFigure):
""" MatplotlibFigure. """
def __init__(self, layout=PlottingLayout(), use_legend=True, xtitle=None, ytitle=None, title=None,
linewidth=None, xlim=None, ylim=None, logx=None, logy=None, xscale=None, yscale=None,
grid=None, ordinates=None, tag=None, labels=None, figsize=(9,6), savefig=None, dpi=None):
super(MatplotlibFigure, self).__init__(title=title, layout=layout,
xtitle=xtitle, ytitle=ytitle, logx=logx, logy=logy)
self.use_legend = use_legend
self.linewidth = linewidth
self.xscale = xscale
self.yscale = yscale
self.grid = grid
self.ordinates = ordinates
self.tag = tag
self.labels = labels
self.figsize = figsize
self.savefig = savefig
self.dpi = dpi
[docs] def render(self):
""" Plot the figure. Call this last."""
fig, ax = plt.subplots(num=None, figsize=self.figsize, facecolor='w', edgecolor='k')
have_labels = False
show_legend = False # override self.use_legend if user called plot with showlegend=True
for dataset in self.getDatasets():
kwargs = {}
if 'name' in dataset:
kwargs['label'] = dataset['name']
have_labels = True
if 'color' in dataset:
kwargs['color'] = dataset['color']
if 'alpha' in dataset and dataset['alpha'] is not None:
kwargs['alpha'] = dataset['alpha']
if 'showlegend' in dataset and dataset['showlegend'] is not None:
show_legend = dataset['showlegend']
if 'color' in dataset and dataset['color'] is not None:
kwargs['color'] = dataset['color']
scatter = False
marker = ''
if 'mode' in dataset and dataset['mode'] is not None:
if dataset['mode'] == 'markers':
scatter = True
marker = ''
if 'dash' in dataset and dataset['dash'] is not None:
kwargs['dashes'] = [4,2]
if 'text' in dataset and dataset['text'] is not None:
for x,y,t in zip(dataset['x'], dataset['y'], dataset['text']):
plt.text(x, y, t, bbox=dict(facecolor='white', alpha=1))
elif not scatter:
plt.plot(dataset['x'], dataset['y'], marker=marker, linewidth=self.linewidth, **kwargs)
else:
plt.scatter(dataset['x'], dataset['y'], **kwargs)
# TODO: data as points
# title & axes labels
if self.title:
ax.set_title(self.title, fontweight='bold')
if self.xtitle:
ax.set_xlabel(self.xtitle, fontweight='bold')
if self.ytitle:
ax.set_ylabel(self.ytitle, fontweight="bold")
# axes limits
if self.xlim:
ax.set_xlim(self.xlim)
if self.ylim:
ax.set_ylim(self.ylim)
# axes type
if self.logx or self.xscale == 'log':
ax.set_xscale('log')
elif self.xscale != None:
ax.set_xscale(self.xscale)
if self.logy or self.yscale == 'log':
ax.set_yscale('log')
elif self.yscale != None:
ax.set_yscale(self.yscale)
# grid
if self.grid:
ax.grid(linestyle='dotted', alpha=0.8)
# TODO: implement ordinates, tags & labels
# legend
if (self.use_legend and have_labels) or show_legend:
if not IPYTHON:
legend = plt.legend()
else:
# legend = plt.legend(bbox_to_anchor=(1.0, 0.5), loc='center left', borderaxespad=1.)
# legend = plt.legend(bbox_to_anchor=(0.0, 1.02, 1., .102), ncol=2, loc='best', borderaxespad=0.)
legend = plt.legend(ncol=1, loc='best', borderaxespad=0.)
# legend.draw_frame(False)
legend.draw_frame(True)
# save figure
if self.savefig:
plt.savefig(self.savefig, dpi=self.dpi, bbox_inches='tight')
print('saved plot to {}'.format(self.savefig))
plt.show()
return fig
# FIXME: integrate old code
# Old code:
# if loc is False:
# loc = None
#
# if 'linewidth' not in kwargs:
# kwargs['linewidth'] = 2.0
#
# # get the names
# names = result.dtype.names
# if names is None:
# names = self.selections
#
# # check if set_prop_cycle is supported
# if hasattr(plt.gca(), 'set_prop_cycle'):
# # reset color cycle (repeated simulations have the same colors)
# plt.gca().set_prop_cycle(None)
#
# # make plot
# Ncol = result.shape[1]
# if len(names) != Ncol:
# raise Exception('Legend names must match result array')
# for k in range(1, Ncol):
# if loc is None:
# # no labels if no legend
# plt.plot(result[:, 0], result[:, k], **kwargs)
# else:
# plt.plot(result[:, 0], result[:, k], label=names[k], **kwargs)
#
# cmap = plt.get_cmap('Blues')
#
# # labels
# if xlabel is None:
# xlabel = names[0]
# plt.xlabel(xlabel)
# if ylabel is not None:
# plt.ylabel(ylabel)
# if title is not None:
# plt.title(title)
# if xlim is not None:
# plt.xlim(xlim)
# if ylim is not None:
# plt.ylim(ylim)
# # axis and grids
# plt.xscale(xscale)
# plt.yscale(yscale)
# plt.grid(grid)
#
# # show legend
# if loc is not None:
# plt.legend(loc=loc)
# # show plot
# if show:
# plt.show()
# return plt