Extremely fast, lightweight timeseries charts for Python — powered by uPlot
Project description
youplot
Extremely fast, lightweight timeseries charts for Python — powered by uPlot.
Write Python. Get a fully self-contained, interactive HTML file. No server. No viewer dependencies.
pip install youplot
Requires Python 3.10+. No runtime dependencies.
Benchmark (Apple M2 Pro, Python 3.11, 3 series, median of 3 runs)
| Library | 1K pts | 10K pts | 100K pts | 500K pts | Output |
|---|---|---|---|---|---|
| youplot | 2ms | 18ms | 176ms | 892ms | Interactive HTML |
| Plotly | 16ms | 81ms | 676ms | 3.36s | Interactive HTML |
| Bokeh | 27ms | 100ms | 835ms | 4.14s | Interactive HTML |
| Matplotlib | 95ms | 125ms | 355ms | 926ms | Static PNG † |
† Matplotlib produces a static raster image with no interactivity.
At 500K points: 3.8× faster than Plotly, 4.6× faster than Bokeh.
youplot's bundled JS runtime is 50 KB; Plotly's is 3.5 MB.
Run python benchmark.py to reproduce.
Quickstart
import youplot as fp
# Unix milliseconds on the x axis
ts_ms = [1_700_000_000_000 + i * 1000 for i in range(86_400)]
fig = fp.Figure(title="24h Temperature", zoom=True, legend=True)
fig.line(ts_ms, temp, label="°C", color="#f97316", fill=True)
fig.band(y_lo=18, y_hi=24, label="Comfort", color="#10b981")
fig.vline(x=ts_ms[3600], label="Event", color="#dc2626")
fig.save("temperature.html") # open in any browser, no install
Multi-chart dashboard with crosshair sync
fig1 = fp.Figure(title="Engine", height=380, zoom=True)
fig1.line(ts_ms, coolant, label="Coolant °C", color="#ef4444")
fig1.line(ts_ms, oil, label="Oil °C", color="#f97316", dash=True)
fig1.tag(x_start=fault_start, x_end=fault_end, label="Fault window")
fig1.pin(ts_ms[peak_idx], label="Peak: 127°C", y_frac=0.1)
fig2 = fp.Figure(title="RPM & Fuel", height=280, zoom=True)
fig2.line(ts_ms, rpm, label="RPM", color="#6366f1")
fig2.line(ts_ms, fuel_psi, label="Fuel PSI", color="#16a34a")
# Hover on one → cursor syncs on both, each shows its own tooltip
dash = fig1 + fig2 # or fp.combine(fig1, fig2)
dash.save("engine.html")
API
Figure
fig = fp.Figure(
title = "My Chart",
subtitle = "Optional subtitle",
theme = "light", # "light" | "dark"
height = 400,
width = None, # None = 100% container width
y_label = "Signal",
zoom = True, # toolbar: zoom/tag/measure/annotate/export
legend = True,
)
All methods return self for chaining.
fig.line()
fig.line(x, y, label="", color=None, width=2.0, dash=False,
fill=False, fill_opacity=0.15, points=False, step=False,
hover_unit="", hover_format="")
fig.scatter()
fig.scatter(x, y, label="", color=None, size=6.0,
size_by=None, color_by=None, shape="circle",
trendline=False, jitter_x=0.0, jitter_y=0.0)
fig.band()
fig.band(y_lo=18, y_hi=24, label="Comfort", color="#10b981", opacity=0.12)
fig.vline() / fig.hline()
fig.vline(x=ts_ms[fault_idx], label="Fault", color="#dc2626")
fig.hline(y=100, label="Max safe", color="#f97316", dash=True)
fig.region()
fig.region(x_start=ts_ms[0], x_end=ts_ms[3600], label="Night",
color="indigo", opacity=0.06)
fig.tag()
Named region with a coloured header band and clickable bubble below the chart.
fig.tag(x_start=ts_ms[fault_start], x_end=ts_ms[fault_end],
label="Fault window", color="#f43f5e", removable=True)
fig.pin()
Annotation pin on the canvas + sticky-note card below the chart.
fig.pin(x=ts_ms[peak_idx], label="Peak: 127°C", y_frac=0.1, color="")
y_frac sets vertical position: 0 = top of plot, 1 = bottom.
Leave color="" to auto-cycle through the annotation palette.
Output
fig.save("out.html") # write to disk, returns path
fig.show() # save to /tmp, open in browser
html = fig.to_html() # return HTML string
frag = fig.to_fragment() # fragment (no <head>/<body>) for embedding
Dashboard / combine
dash = fig1 + fig2 + fig3 # operator
dash = fp.combine(fig1, fig2, fig3, title="...") # function
dash = fp.Dashboard(title="...").add(fig1).add(fig2) # builder
dash.save("dashboard.html")
dash.show()
Colors
- Hex:
"#f43f5e" - Named:
"rose""indigo""emerald""orange""violet""cyan""amber""pink""lime""teal" None— auto-cycles per Figure
Themes
fp.Figure(theme="light") # default
fp.Figure(theme="dark")
UI Tools (when zoom=True)
| Tool | How to use |
|---|---|
| Zoom | Left-drag X to zoom. Vertical drag zooms Y. Double-click resets. |
| Tag | Drag to name a region. Click bubble to navigate. |
| Measure | Click anchor, move to see ΔX/ΔY live. |
| Annotate | Click to drop a pin. |
| Export | Download current state (tags + annotations) as HTML. |
Built on uPlot
youplot is a Python API layer over uPlot by Leon Sorokin.
uPlot renders 1M points in <35ms, ships at 50KB with zero dependencies.
All rendering performance comes from uPlot. Please ⭐ the repository.
License
MIT © youplot contributors
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file youplot-1.0.0.tar.gz.
File metadata
- Download URL: youplot-1.0.0.tar.gz
- Upload date:
- Size: 69.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ccec6b53da915fb685e8ebaac6c3ff25db6cee105365e73410d27c76af954b1e
|
|
| MD5 |
ed6765bd9175d08c0d6654dfff283e31
|
|
| BLAKE2b-256 |
cea2c1d04a61e906f908546d0fe0f948405ff1aa77780bc1b8eae6fc5cb81302
|
File details
Details for the file youplot-1.0.0-py3-none-any.whl.
File metadata
- Download URL: youplot-1.0.0-py3-none-any.whl
- Upload date:
- Size: 72.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31fe55753a3a073ba1bf2979708443d87d11bb9e0250a0c1ab23118e1e70fb94
|
|
| MD5 |
b2b35bbd013cc208f5e6842b5e6eea98
|
|
| BLAKE2b-256 |
5ec5accc3493d035acf6956e6b3e26bef1f5bad9f11dbeeb279f16e0c0da2533
|