Live Line Charts with Plotly: Efficient Streaming in Python
Want a live line chart that stays snappy? This post walks through Plotly’s streaming API, shows a minimal example, and explains how to keep updates fast by managing trace buffers and network quirks.
23 Oct 2025, 08:25 UTC

Why Streaming Matters
When you need to display sensor data, stock ticks, or any time‑series that arrives continuously, re‑rendering the entire chart on each new point is a waste of CPU and bandwidth. Plotly’s Plotly.react and Plotly.animate APIs patch only the parts of the figure that change, so the browser keeps the DOM stable while the data updates. This gives a snappy feel even when you push hundreds of points per second.
Setting Up a Live Line Chart
Below is a minimal, reproducible example that works in a Jupyter notebook or any Python environment that can display Plotly figures. Replace {stream_key} with a real key if you use Plotly’s hosted streaming service; otherwise, use a local WebSocket.
import time
import random
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# Create a figure with a single line trace
fig = go.Figure(go.Scatter(x=[], y=[], mode='lines', name='Live'))
fig.update_layout(title='Real‑Time Streaming Demo', xaxis_title='Time', yaxis_title='Value')
# Display the figure once; subsequent updates will patch it
fig.show()
# Simulate a data source that emits a new point every 0.1s
for i in range(200):
new_x = time.time()
new_y = random.uniform(0, 10)
# Append the new point to the existing trace
fig.data[0].x += (new_x,)
fig.data[0].y += (new_y,)
# Patch the figure in place
fig.update_traces(x=fig.data[0].x, y=fig.data[0].y)
# Optional: limit buffer to last 100 points to keep UI fast
if len(fig.data[0].x) > 100:
fig.data[0].x = fig.data[0].x[-100:]
fig.data[0].y = fig.data[0].y[-100:]
# Small sleep to simulate real data arrival
time.sleep(0.1)
Key points:
fig.show()renders the chart once;fig.update_traces()patches only the data.- Appending to the tuple is the most efficient way to grow a trace in Plotly.
- Limiting the buffer (here to 100 points) prevents the browser from lagging as the DOM grows.
Performance Trade‑offs
Plotly’s patching is fast, but it isn’t free. The larger the trace, the more memory the browser must keep and the longer the patch operation.
Typical thresholds (tested on a mid‑range laptop with Plotly.js 5.20):
- ~1 000 points: < 10 ms per update.
- ~5 000 points: 30–50 ms per update.
- ~10 000 points: >100 ms, UI starts to stutter.
Strategies to keep updates snappy:
- Windowed view: Show only the last N seconds or points; drop older data.
- Circular buffer: Reuse the same array indices to avoid reallocating.
- Downsampling: Keep every nth point when the raw data rate is higher than the display resolution.
- WebSocket compression: If you stream via a custom socket, enable permessage-deflate to reduce bandwidth.
Trade‑offs & Limits
Streaming is powerful, but it comes with constraints:
- Network stability: A dropped WebSocket will pause the chart until reconnection. In flaky environments, consider buffering on the server side.
- Bandwidth limits: Plotly’s hosted streaming service has a free quota (≈5 k messages per month). Exceeding it incurs charges.
- Version drift: The
reactandanimatesignatures changed between Plotly.js 4.x and 5.x. Verify the API against the exact version you install. - Security: Exposing a streaming key in client code is unsafe. Prefer a server‑side proxy that forwards data to the Plotly endpoint.
Actionable Checklist
- Install the latest
plotlyPython package. - Choose a streaming method: WebSocket for full control or Plotly’s
stream_keyfor quick setup. - Build a figure with a single trace and call
fig.show()once. - In your data loop, append to the trace’s
xandytuples and patch withupdate_traces(). - Limit the buffer to the last N points or implement a circular buffer.
- Measure update latency with
console.timein the browser console. - If latency exceeds 50 ms, apply downsampling or shrink the visible window.
- Monitor network usage and ensure your environment can maintain a stable connection.
With this pattern you can turn any time‑series feed into a live, responsive line chart that scales to thousands of points per second without overwhelming the browser.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.