Source code for tellurium.plotting.engine_plotly

"""
Plotly implementation of the plotting engine.
"""
from __future__ import print_function, absolute_import

from .engine import PlottingEngine, PlottingFigure, PlottingLayout, filterWithSelections, TiledFigure, LowerTriFigure
import numpy as np
import plotly
from plotly.graph_objs import Scatter, Scatter3d, Layout, Data, Marker
from plotly import tools


[docs] class PlotlyEngine(PlottingEngine): """ PlottingEngine using plotly. """ def __init__(self): PlottingEngine.__init__(self) def __str__(self): return "<PlotlyEngine>"
[docs] def newFigure(self, title=None, logX=False, logY=False, layout=PlottingLayout(), xlabel=None, ylabel=None): """ Returns a figure object.""" return PlotlyFigure(title=title, layout=layout, xlabel=xlabel, ylabel=ylabel)
[docs] def newStackedFigure(self, title=None, logX=False, logY=False, layout=PlottingLayout()): """ Returns a figure object.""" return PlotlyStackedFigure(title=title, layout=layout)
[docs] def newTiledFigure(self, title=None, rows=None, cols=None): return PlotlyTiledFigure(engine=self, rows=rows, cols=cols)
[docs] def newLowerTriFigure(self, title=None, rows=None, cols=None): return PlotlyLowerTriFigure(engine=self, rows=rows, cols=cols)
[docs] class PlotlyFigure(PlottingFigure): """ PlotlyFigure. """ def __init__(self, title=None, layout=PlottingLayout(), logx=False, logy=False, save_to_pdf=False, xlabel=None, ylabel=None): super(PlotlyFigure, self).__init__(title=title, layout=layout, logx=logx, xlabel=xlabel, logy=logy, ylabel=ylabel)
[docs] def getArgsForDataset(self, dataset): kwargs = {} kwargs['mode'] = 'lines' if 'name' in dataset and dataset['name'] is not None: kwargs['name'] = dataset['name'] else: kwargs['showlegend'] = False if 'showlegend' in dataset and dataset['showlegend'] is not None: # override with user-specified legend setting kwargs['showlegend'] = dataset['showlegend'] if 'alpha' in dataset and dataset['alpha'] is not None: kwargs['opacity'] = dataset['alpha'] if 'text' in dataset and dataset['text'] is not None: kwargs['text'] = dataset['text'] kwargs['textposition'] = 'bottom center' kwargs['mode'] = 'markers+text' kwargs['marker']=Marker(color='black') if 'color' in dataset and dataset['color'] is not None: kwargs['marker']=Marker(color=dataset['color']) # lines/markers (lines by default) if 'mode' in dataset and dataset['mode'] is not None: kwargs['mode'] = dataset['mode'] if 'dash' in dataset and dataset['dash'] is not None: kwargs['line'] = {'dash': dataset['dash']} # override mode via scatter if 'scatter' in dataset and dataset['scatter'] == True: kwargs['mode'] = 'markers' if 'error_y_pos' in dataset and dataset['error_y_pos'] is not None and 'error_y_neg' in dataset and dataset['error_y_neg'] is not None: kwargs['error_y'] = dict( type='data', symmetric=False, array=dataset['error_y_pos'], arrayminus=dataset['error_y_neg'], visible=True, ) return kwargs
[docs] def getScatterGOs(self): for dataset in self.getDatasets(): yield Scatter( x = dataset['x'], y = dataset['y'], **self.getArgsForDataset(dataset) )
[docs] def render(self): """ Plot the figure. Call this last.""" traces = list(self.getScatterGOs()) data = Data(traces) plotly.offline.iplot({ 'data': data, 'layout': self.makeLayout() })
[docs] def save(self, filename, format): # FIXME: implement raise NotImplementedError
[docs] def makeLayout(self): kwargs = {} if self.title is not None: kwargs['title'] = self.title if self.logx: kwargs['xaxis'] = { 'type': 'log', 'autorange': True, } if self.xlabel: if not 'xaxis' in kwargs: kwargs['xaxis'] = {} kwargs['xaxis']['title'] = self.xlabel if self.logy: kwargs['yaxis'] = { 'type': 'log', 'autorange': True, } if self.ylabel: if not 'yaxis' in kwargs: kwargs['yaxis'] = {} kwargs['yaxis']['title'] = self.ylabel if not self.grid_enabled: kwargs['xaxis']['showgrid'] = False kwargs['xaxis']['showline'] = False kwargs['yaxis']['showgrid'] = False kwargs['yaxis']['showline'] = False return Layout(**kwargs)
[docs] class PlotlyStackedFigure(PlotlyFigure): """ Stacked figure.""" def __init__(self, title=None, layout=PlottingLayout(), logx=False, logy=False): super(PlotlyStackedFigure, self).__init__(title=title, layout=layout, logx=logx, logy=logy) self.zindex = 0
[docs] def render(self): """ Plot the figure. Call this last.""" traces = [] for dataset in self.xy_datasets: kwargs = {} if 'name' in dataset and dataset['name'] is not None: kwargs['name'] = dataset['name'] self.zindex = kwargs['name'] else: kwargs['showlegend'] = False zvals = np.full(np.size(dataset['x']), self.zindex) traces.append(Scatter3d( x = dataset['x'], z = dataset['y'], y = zvals, mode = 'lines', **kwargs )) if not isinstance(self.zindex, str): self.zindex += 1 data = Data(traces) plotly.offline.iplot({ 'data': data, 'layout': self.makeLayout() })
[docs] class PlotlyTiledFigure(TiledFigure): def __init__(self, engine, rows, cols): self.rows = rows self.rowmarker = 0 self.cols = cols self.colmarker = 0 self.engine = engine #self.fig = None self.figures = []
[docs] def nextFigure(self, *args, **kwargs): self.cycleMarker() fig = self.engine.newFigure(*args, **kwargs) self.figures.append(fig) return fig
[docs] def renderIfExhausted(self): if not self.isExhausted(): return False fig = tools.make_subplots(self.rows, self.cols, subplot_titles=tuple(f.title for f in self.figures), print_grid=False) row = 1 col = 1 n = 1 for f in self.figures: for trace in f.getScatterGOs(): fig.append_trace(trace, row, col) if f.logx: fig['layout']['xaxis'+str(n)]['type'] = 'log' fig['layout']['xaxis'+str(n)]['autorange'] = True if f.logy: fig['layout']['yaxis'+str(n)]['type'] = 'log' fig['layout']['yaxis'+str(n)]['autorange'] = True col += 1 n += 1 if col > self.cols: col = 1 row += 1 if row > self.rows: row = self.rows plotly.offline.iplot(fig) return True
[docs] class PlotlyLowerTriFigure(PlotlyTiledFigure,LowerTriFigure):
[docs] def makeTitles(self): row = 1 col = 1 for f in self.figures: yield f.title col += 1 if col > row: while col <= self.cols: col += 1 yield '' col = 1 row += 1 if row > self.rows: return;
[docs] def renderIfExhausted(self): if not self.isExhausted(): return False fig = tools.make_subplots(self.rows, self.cols, subplot_titles=tuple(self.makeTitles()), print_grid=False) row = 1 col = 1 n = 1 for f in self.figures: for trace in f.getScatterGOs(): fig.append_trace(trace, row, col) col += 1 n += 1 if col > row: while col <= self.cols: for key in ('xaxis'+str(n), 'yaxis'+str(n)): fig['layout'][key]['showgrid'] = False fig['layout'][key]['showline'] = False fig['layout'][key]['showticklabels'] = False fig['layout'][key]['ticks'] = '' fig['layout'][key]['zeroline'] = False n+=1 col+=1 col = 1 row += 1 if row > self.rows: row = self.rows plotly.offline.iplot(fig) return True