plotly is a great resource for making interactive plots in the notebook, which are then backed up to a cloud and easily shared and collaborated upon through their web app. We use plotly to back up our experimental data into interactive notebooks, which other students in our lab can then access through the web app, add annotation and explore the data.
skspec
supports plotly through the both the excellent matplotlib wrapper (pass in a matplotlib plot, get out a plotly plot) and to a limited extent, through it's own API.
Configure notebook style (see NBCONFIG.ipynb), add imports and paths. The %run magic used below requires IPython 2.0 or higher.
%run NBCONFIG.ipynb
Populating the interactive namespace from numpy and matplotlib
To use plotly, you need an account (this will automatically sync your generated plots to the web). You can then either sign in directly:
- import plotly.plotly as py
- py.sign_in(<user>, <key>)
Or store your credentials in the plotly credentials file, and then call them as done below. To set the credentials:
- import plotly.tools as tls
- tls.set_credentials_file(username=<user>, api_key=<key>, ...)
Run help(tls.set_credentials_file)
for full description.
import plotly.plotly as py
import plotly.tools as tls
creds = tls.get_credentials_file()
py.sign_in(creds['username'], creds['api_key'])
Let's import a test spectral and plot it in matplotlib.
from skspec.data import aunps_water
ts = aunps_water()
ts = ts.as_interval('s')
ts.plot();
WARNING:skspec.core.timespectra:SpecIndex unit was changed internally from "None" to "nm"
If we want to make the equivalent plotly plot, then we need to use mpl.subplots to generate a figure. This figure is then passed to plotly! Just past that axes instance right into any skspec plotting call.
fig, ax = plt.subplots(1,1)
ts.plot(ax=ax)
py.iplot_mpl(fig)
Notice we made use of plotly's iplot_mpl()
wrapper. This does a good job of converting matplotlib figures to plotly while preserving most plot features. The mapping is not always perfect, so we can update plot features (requires plotly 1.0.27 or higher) as follows:
Keep in mind that when updating the layout, font, lines and other seperate plotting aspects, nested dictionaries are requried. Run 'help(plotly.graph_objs.Figure)' for more information.
figure_update = dict(
layout =
dict(
showlegend = True,
font = dict(size=20),
plot_bgcolor='rgb(200,200,200)'
),
)
py.iplot_mpl(fig, update=figure_update);
For convienence, if you are using NBCONFIG.ipynb (see top cell of this notebook), then you already have some default plotly update settings in the variable _pyupdate
!
This will be used in mplt_iplot() in the following sections.
_pyupdate
{'layout': {'font': {'size': 9}, 'plot_bgcolor': 'rgb(191,191,191)'}}
pyparty 0.2
comes with a limited direct plotly API. For now, most of the behavior available can be gotten through the iplot_mpl()
wrapper as shown above, but soon we hope to provide better support for plotly streaming, among other featuers.
from skspec.plotting.plotlywrapper import ply_fig
fig = ply_fig(ts,
color='jet',
width=5,
opacity=0.2)
py.iplot(fig)
Notice that ply_figure
accepts plotly keywords and not matplotlib keywords (ie opacity instead of alpha).
ply_fig
interprets all keywords as line options (eg width, opacity); however, layout keywords can be passed as well. This design choice deviates from updating through iplot_mpl (i.e iplot_mpl(update=...) )
in that we don't support all types of nested dictionaries. Therefore, I don't recommend using ply_fig
if iplot_mpl()
can suffice!
fig = ply_fig(ts,
color='bone',
opacity=0.1,
width=0.0001,
layout=dict(title='Recolored',
showlegend=True,
plot_bgcolor = 'rgb(128,0,0)'
)
)
py.iplot(fig)
Area plot directly from ts and ply_fig, as opposed to skspec.plotting.areaplot()
area = ts.area().transpose()
fig = ply_fig(area,
color='purple',
points=True,
layout={'title':'Area vs. Time'}
)
py.iplot(fig, resize=False)
Averaging different wavelength slices with the range_timeplot, both in mpl and plotly.
from skspec.plotting import range_timeplot
range_timeplot(ts.wavelength_slices(8));
fig, ax = plt.subplots(1,1)
range_timeplot(ts.wavelength_slices(8), ax=ax)
py.iplot_mpl(fig, update=_pyupdate, resize=False)
f, axes = plt.subplots(1,3, figsize=(8,5))
ts.name = '' #Removes title from subplots
ts.sub_base() #subtract builtin baseline
absorb = ts.as_iunit('a').ix[400.0:700.0]
absorb.plot(ax=axes[0])
absorb.plot(ax=axes[1], colormap='gray', sharey=axes[0])
absorb.plot(ax=axes[2], colormap='autumn', sharey=axes[0]);
CRITICAL:skspec.core.timespectra:Subtracting baseline, but may not have all: elements being equal. Fix index
py.iplot_mpl(f, update=_pyupdate,)
Using plotly interactively, we can easily see the surface plasmon resonance shift is about 3nm (525-528nm) due to protein binding.
from skspec.plotting import plot3d
#NEEDS TO RETURN FIG/AX ETC... (rename colormap, "WAVELENGTH" other axis labels, CHOOSE BETTER DEFAULT TIMES...)
plot3d(absorb, cmap='bone', alpha=.5, elev=25, azim=15);