From your last email:
[...] what I had in mind was not to stream data through the y=sin(x) curves per se. Rather, I want the animation to plot the subsequent y curves after a given time interval. So for example:
The curves y(x) are static, merely plotting them increments with time. Is something like this available?
Absolutely.
Plotly allows you to either append a given state (like in the last example) or overwrite it (like I will show you here); hence, plotting full curves in sequence.
This notebook has more on the topic.
Again, 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
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, 1 per trace
# 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, 1 per trace
# Package them into data object
my_data = Data([my_scatter1, my_scatter2])
# Layout object
my_layout = Layout(title='A shared axes simulation', # plot's title
xaxis= XAxis(range=[0,2*np.pi]),
yaxis1= YAxis(domain=[0.0, 0.475], # bottom yaxis domain
range=[-1.3,1.3]), # and range
yaxis2= YAxis(domain=[0.525, 1.0], # top yaxis domain
range=[-1.3,1.3]) # 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-axis2')
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()
--------------------------------------------------------------------------- gaierror Traceback (most recent call last) <ipython-input-9-607b23594229> in <module>() 2 # with same stream id as the first Stream id object and open the stream 3 s1 = py.Stream(my_stream_id1) ----> 4 s1.open() 5 6 # Make a second instance of the Stream link object, /usr/local/lib/python2.7/dist-packages/plotly/plotly/plotly.pyc in open(self) 366 80, 367 {'Host': 'stream.plot.ly', --> 368 'plotly-streamtoken': self.stream_id}) 369 370 /usr/local/lib/python2.7/dist-packages/plotly/plotly/chunked_requests/chunked_request.pyc in __init__(self, server, port, headers) 16 self._port = port 17 self._headers = headers ---> 18 self._connect() 19 20 def write(self, data, reconnect_on=('', 200, )): /usr/local/lib/python2.7/dist-packages/plotly/plotly/chunked_requests/chunked_request.pyc in _connect(self) 80 for header in headers: 81 self._conn.putheader(header, headers[header]) ---> 82 self._conn.endheaders() 83 84 # Set blocking to False prevents recv /usr/lib/python2.7/httplib.pyc in endheaders(self, message_body) 967 else: 968 raise CannotSendHeader() --> 969 self._send_output(message_body) 970 971 def request(self, method, url, body=None, headers={}): /usr/lib/python2.7/httplib.pyc in _send_output(self, message_body) 827 msg += message_body 828 message_body = None --> 829 self.send(msg) 830 if message_body is not None: 831 #message_body was not a string (i.e. it is a file) and /usr/lib/python2.7/httplib.pyc in send(self, data) 789 if self.sock is None: 790 if self.auto_open: --> 791 self.connect() 792 else: 793 raise NotConnected() /usr/lib/python2.7/httplib.pyc in connect(self) 770 """Connect to the host and port specified in __init__.""" 771 self.sock = socket.create_connection((self.host,self.port), --> 772 self.timeout, self.source_address) 773 774 if self._tunnel_host: /usr/lib/python2.7/socket.pyc in create_connection(address, timeout, source_address) 551 host, port = address 552 err = None --> 553 for res in getaddrinfo(host, port, 0, SOCK_STREAM): 554 af, socktype, proto, canonname, sa = res 555 sock = None gaierror: [Errno -2] Name or service not known
And now stream some data:
# Make list of arrays of data pts from [0,pi/2], [pi/2,pi], [pi,3*pi/2], [3*pi/2,pi]
dx = 0.1 # spacing between data points
X = [np.arange(0,np.pi/2,dx),
np.arange(np.pi/2,np.pi,dx),
np.arange(np.pi,3*np.pi/2,dx),
np.arange(3*np.pi/2,2*np.pi,dx)]
time.sleep(1) # wait 1 sec
for x in X: # loop through list of arrays
s1_data = dict(x=x, y=np.sin(x)) # data for stream 1
# N.B. both x and np.sin(x) are lists
# (i.e. not numbers)
# so the current state is overwritten!
s1.write(s1_data) # send data to stream 1
time.sleep(1) # wait 1 sec
s2_data = dict(x=x, y=np.sin(2*x)) # data for stream 2
# N.B. again both x and np.sin(2*x) are lists!
s2.write(s2_data) # send data to stream 2
time.sleep(1) # wait 1 sec
# Close both streams when done
s1.close()
s2.close()
See the results right inside this notebook above.
Note that, in this example, the two lines first plotted disappearer when they are overwritten. To see all eight traces on the plot at the end of the simulation either:
Use eight unique stream tokens, plotting each trace sequentially to different streams
Or, use
# 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-axis2b')
s1.open()
s2.open()
time.sleep(1) # wait 1 sec
xx = np.array([])
for x in X: # loop through list of arrays
xx = np.append(xx,x)
y1 = np.sin(xx)
s1_data = dict(x=xx, y=y1) # data for stream 1
s1.write(s1_data) # send data to stream 1
time.sleep(1) # wait 1 sec
y2 = np.sin(2*xx)
s2_data = dict(x=xx, y=y2) # data for stream 2
s2.write(s2_data) # send data to stream 2
time.sleep(1) # wait 1 sec
# 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()