From your last email:
I guess for now, we will hold off on streaming our curves, since there are something like 1000-5000 curves per data set, and we'd need to generate that many stream ID's.
Hmmm.
Are you thinking about plotting those 1000-5000 curves in succession on top of one another?
Or, are you thinking about plotting 1000-5000 curves in succession but only showing one curve at a time on the plot?
Because if your situation is like the latter, you only really need 1 stream token (or 2 two if you still want to plot data on two y axes) to do so.
The former (which I am having a hard time imagining its context) would require as many stream tokens are curves to be plotted, in order to keep the information of each curve throughout the exercise.
Stream tokens are really stream ids serving to locate the destination of the data to be streamed with Plotly's streaming API. If you have a set of curves meant to be plotted at the same destination (i.e. the same set of axes) and that those curves are not to be shown at the same time, then you can use the same stream token to plot all those curves. This is done by overwritting the data on the plot at each stream write (i.e.
py.Stream.write()
) call.
This notebook will show you an example.
First import a few modules:
import plotly.plotly as py
import plotly.tools as tls
from plotly.graph_objs import Figure, Data, Layout
from plotly.graph_objs import Scatter
from plotly.graph_objs import XAxis, YAxis, Annotation
from plotly.graph_objs import Stream # aka Stream id object
import numpy as np
import time
Next, retrieve the stream ids in your credentials file as a list:
# Get stream ids in credentials file
my_stream_ids = tls.get_credentials_file()['stream_ids']
Make two instances of the stream id object, each with a unique stream token:
# Make a first stream id object
my_stream_id1 = my_stream_ids[0] # get a stream token from list
my_stream1 = Stream(token=my_stream_id1) # N.B. link stream id to 'token' key
# Make a second stream id object
my_stream_id2 = my_stream_ids[1] # get different stream token from list
my_stream2 = Stream(token=my_stream_id2)
Before starting to stream data, we must first initialize the figure object:
# Scatter object for sin(x) line
my_scatter1 = Scatter(x=[],
y=[],
mode='lines+markers',
name='$y_1 = \sin(x)$', # label for legend
yaxis='y1', # N.B. link data to y-axis 1
stream=my_stream1) # N.B. embed stream id
# Scatter object for sin(2x) line
my_scatter2 = Scatter(x=[],
y=[],
mode='lines+markers',
name='$y_2 = \sin(2x)$',
yaxis='y2', # N.B. link data to y-axis 2
stream=my_stream2) # N.B. embed stream id
# Package them into data object
my_data = Data([my_scatter1, my_scatter2])
# Layout object
my_layout = Layout(title='Plotting curves in succession', # plot's title
xaxis1= XAxis(range=[-0.1,6.5]), # xaxis (shared) range
yaxis1= YAxis(domain=[0.0, 0.475], # bottom yaxis domain
range=[-2.1,2.1]), # and range
yaxis2= YAxis(domain=[0.525, 1.0], # top yaxis domain
range=[-2.1,2.1]) # and range
)
# Make instance of figure object
my_fig = Figure(data=my_data, layout=my_layout)
# Initialize streaming plot, show result in notebook
py.iplot(my_fig, filename='stream-shared-axis3')
Next, open both streams via the stream link object:
# Make a first instance of the Stream link object,
# with same stream id as the first Stream id object and open the stream
s1 = py.Stream(my_stream_id1)
s1.open()
# Make a second instance of the Stream link object,
# with same stream id as the second Stream id object and open the stream
s2 = py.Stream(my_stream_id2)
s2.open()
And now stream some data:
N = 30 # number of curved to be plotted
i = 0 # init. counter
dx = 0.1 # spacing between data points
xx = np.arange(0,2*np.pi,dx)
# Make list of curves to be plotted
curves1 = [np.sin(xx)+np.random.rand(len(xx))-0.5 for i in range(N)]
curves2 = [np.sin(2*xx)+np.random.rand(len(xx))-0.5 for i in range(N)]
# Make list of annotations
def make_anno(yref_in,text_in):
return Annotation(x=0.1,yref=yref_in,y=1.6,
text='<b>Curve '+str(text_in)+'</b>',showarrow=False)
anno1 = [make_anno('y1',i) for i in range(1,2*(N+1),2)]
anno2 = [make_anno('y2',i) for i in range(2,2*(N+1),2)]
for i in range(N): # loop through the curves' indices
s1_data = dict(x=xx, y=curves1[i]) # N.B. data for stream 1
# overwrite current data on plot
# as we are sending lists of numbers
s1_layout = dict(annotations=[anno1[i]]) # annotation for stream 1
s1.write(s1_data, layout=s1_layout) # send data to stream 1
time.sleep(1) # wait 1 second
s2_data = dict(x=xx, y=curves2[i]) # N.B. data for stream 2
# overwrite current data on plot
# as we are sending lists of numbers
s2_layout = dict(annotations=[anno2[i]]) # annotation for stream 2
s2.write(s2_data, layout=s2_layout) # send data to stream 2
time.sleep(1) # wait 1 second
# Close both streams when done
s1.close()
s2.close()
About Plotly
Big thanks to
# CSS styling within IPython notebook
from IPython.core.display import HTML
import urllib2
def css_styling():
url = 'https://raw.githubusercontent.com/plotly/python-user-guide/master/custom.css'
styles = urllib2.urlopen(url).read()
return HTML(styles)
css_styling()