Python wrapper for the dygraphs JavaScript charting library. Core port of R dygraphs with framework adapters for Dash and Shiny.
Project description
pydygraphs
Python wrapper for the dygraphs JavaScript charting library.
Core port of the R dygraphs package — all 44 exported R functions ported to a Pythonic builder API. The R package (by RStudio/JJ Allaire) is the most mature dygraphs wrapper in any language; pydygraphs faithfully ports its API design, data model, and test coverage to Python.
Framework-agnostic core with adapters for Plotly Dash and Shiny for Python.
Features
- Two API styles: builder chaining (
Dygraph(df).options(...).series(...)) and declarative (Dygraph(df, options=Options(...), series=[Series(...)])) — both produce identical output - Full R port: options, axes, series, legend, highlight, annotations, shadings, events, limits, range selector, roller, callbacks
- Advanced plotters: bar chart, stacked bar, candlestick, multi-column, stem, filled line, error fill + group variants
- Plugins: unzoom, crosshair, ribbon, rebase
- Error bars: symmetric, custom (low/mid/high), fractions with Wilson intervals
- Zoom sync across multiple charts (line + stacked bar)
- Stacked bar chart with interactive canvas range selector
- Modebar overlay (Plotly-style) with PNG download and reset zoom buttons
- Standalone HTML export via
.to_html()— no server needed - dash-capture compatible via
dygraph_strategy() - Framework-agnostic: core builder has zero Dash/Shiny imports
- Flexible data input: DataFrame, Series, dict, list, numpy array, CSV string, CSV file
- Type-safe: full type hints,
py.typed, passestyandruff
Installation
pip install pydygraphs # core only
pip install pydygraphs[dash] # + Plotly Dash adapter
pip install pydygraphs[shiny] # + Shiny for Python adapter
Quick Start
Builder API (chaining)
import pandas as pd
from pydygraphs import Dygraph
df = pd.DataFrame(
{"temp": [10, 12, 11, 14, 13], "rain": [5, 3, 7, 2, 6]},
index=pd.date_range("2024-01-01", periods=5, freq="D"),
)
chart = (
Dygraph(df, title="Weather")
.options(fill_graph=True, draw_points=True, colors=["#00d4aa", "#f4a261"])
.axis("y", label="Value")
.series("temp", stroke_width=2)
.legend(show="always")
.range_selector(height=30)
)
Declarative API
from pydygraphs import Dygraph, Options, Series, Axis, Legend, RangeSelector
chart = Dygraph(
df,
title="Weather",
options=Options(fill_graph=True, draw_points=True, colors=["#00d4aa", "#f4a261"]),
axes=[Axis("y", label="Value")],
series=[Series("temp", stroke_width=2)],
legend=Legend(show="always"),
range_selector=RangeSelector(height=30),
)
Dicts work too — mix freely:
chart = Dygraph(
df,
title="Weather",
options={"fill_graph": True},
series=[Series("temp", color="red"), {"name": "rain", "axis": "y2"}],
)
Render in Dash
from dash import Dash, html
app = Dash(__name__)
app.layout = html.Div([chart.to_dash(app=app)])
Render in Shiny
from pydygraphs.shiny import dygraph_ui, render_dygraph
# In UI:
dygraph_ui("my-chart")
# In server:
await render_dygraph(session, "my-chart", chart)
Standalone HTML
html_string = chart.to_html()
Path("chart.html").write_text(html_string)
Data Input
| Format | Example |
|---|---|
| pandas DataFrame | pd.DataFrame({"y": [1,2,3]}, index=pd.date_range(...)) |
| pandas Series | pd.Series([1,2,3], name="y") |
| dict | {"x": [1,2,3], "y": [10,20,30]} |
| list of rows | [[1, 10], [2, 20], [3, 30]] |
| numpy array | np.array([[1, 10], [2, 20]]) |
| CSV string | "Date,A,B\n2024-01-01,1,2\n..." |
| CSV file | Dygraph.from_csv("data.csv") |
Utility Methods
chart.update(legend={"show": "follow"}) # modify config after construction
forked = chart.copy() # deep copy for variants
config = chart.to_dict() # plain dict (framework-agnostic)
json_str = chart.to_json() # JSON with JS functions
Error Bars
from pydygraphs import Dygraph, make_error_bar_data
data = make_error_bar_data(x=[1,2,3], y=[10,20,30], error=[1,2,3])
chart = Dygraph(data, options={"error_bars": True})
Syncing Multiple Charts
from pydygraphs import sync_dygraphs, stacked_bar
chart_a = Dygraph(df1).range_selector().to_dash(app, component_id="a")
chart_b = Dygraph(df2).range_selector().to_dash(app, component_id="b")
chart_c = stacked_bar(app, "c", csv_data, title="Stacked Bar")
sync = sync_dygraphs(app, ["a", "b", "c"])
app.layout = html.Div([sync, chart_a, chart_b, chart_c])
Dynamic Updates (Dash)
Charts expose dcc.Store components:
Output("{id}-store", "data") # update chart data
Output("{id}-opts", "data") # update options at runtime
Input("{id}-xrange", "data") # read current date window
Capture (dash-capture)
from pydygraphs import dygraph_strategy
from dash_capture import capture_element
capture_element(app, "btn", "chart-container", "img-store",
strategy=dygraph_strategy(hide_range_selector=True))
API Reference
Builder Methods
| Method | R Equivalent | Description |
|---|---|---|
Dygraph(data, ...) |
dygraph() |
Create chart |
.options(...) |
dyOptions() |
Global options |
.axis(name, ...) |
dyAxis() |
Per-axis config |
.series(name, ...) |
dySeries() |
Per-series config |
.group(names, ...) |
dyGroup() |
Group config |
.legend(...) |
dyLegend() |
Legend options |
.highlight(...) |
dyHighlight() |
Highlight behavior |
.annotation(x, text) |
dyAnnotation() |
Data annotations |
.shading(from_, to) |
dyShading() |
Background regions |
.event(x, label) |
dyEvent() |
Vertical event lines |
.limit(value, label) |
dyLimit() |
Horizontal limit lines |
.range_selector(...) |
dyRangeSelector() |
Range selector |
.roller(...) |
dyRoller() |
Rolling average |
.callbacks(...) |
dyCallbacks() |
JS callbacks |
.css(path) |
dyCSS() |
Custom CSS |
.update(...) |
— | Modify config |
.copy() |
— | Deep copy |
.to_dash(app) |
— | Dash component |
.to_shiny(id) |
— | Shiny component |
.to_html() |
— | Standalone HTML |
.to_dict() |
— | Plain dict |
.to_json() |
— | JSON string |
Dygraph.from_csv(path) |
— | Load from CSV file |
Declarative Dataclasses
Options, Axis, Series, Legend, Highlight, Annotation, Shading, Event, Limit, RangeSelector, Roller, Callbacks
All accept the same parameters as their builder counterparts. Pass as dataclass or dict.
Plotters
.bar_chart(), .stacked_bar_chart(), .multi_column(), .candlestick(), .bar_series(name), .stem_series(name), .shadow(name), .filled_line(name), .error_fill(name) + group variants
Also via constructor: Dygraph(df, plotter="bar_chart")
Plugins
.unzoom(), .crosshair(direction), .ribbon(data, palette), .rebase(value, percent)
Development
uv sync --group dev
uv run ruff check src/ tests/
uv run ty check
uv run prek run --all-files
uv run pytest tests/pydygraphs/ # core tests
uv run pytest tests/dash/ # Dash adapter tests
uv run pytest tests/integration/ # Chrome integration tests
License
MIT
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 pydygraphs-0.0.1.tar.gz.
File metadata
- Download URL: pydygraphs-0.0.1.tar.gz
- Upload date:
- Size: 263.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9db80b78c93e8954607301b0809a8cc67f065f3e1f740f5ac9dd929b91f35ca9
|
|
| MD5 |
2048e545265f06cc75582a09b775d90a
|
|
| BLAKE2b-256 |
5ec0d6546c86d5b7f3aab868195d1136c67ee6fec6d7d78330f4d83a82d119a5
|
Provenance
The following attestation bundles were made for pydygraphs-0.0.1.tar.gz:
Publisher:
publish.yml on saemeon/pydygraphs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydygraphs-0.0.1.tar.gz -
Subject digest:
9db80b78c93e8954607301b0809a8cc67f065f3e1f740f5ac9dd929b91f35ca9 - Sigstore transparency entry: 1237031651
- Sigstore integration time:
-
Permalink:
saemeon/pydygraphs@1cf70c622e16b51a319012b839936fdf18f1a057 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/saemeon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1cf70c622e16b51a319012b839936fdf18f1a057 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pydygraphs-0.0.1-py3-none-any.whl.
File metadata
- Download URL: pydygraphs-0.0.1-py3-none-any.whl
- Upload date:
- Size: 105.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba1d112f3537c86c9166a0eecc13595481d72a3484937d4d897082db21582dea
|
|
| MD5 |
72f5936088b2ad75afe38a3a2ad02252
|
|
| BLAKE2b-256 |
7c85514748de3dd733ec832122e53c1548d924bad3f5a438db0e2e6ca448c9af
|
Provenance
The following attestation bundles were made for pydygraphs-0.0.1-py3-none-any.whl:
Publisher:
publish.yml on saemeon/pydygraphs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydygraphs-0.0.1-py3-none-any.whl -
Subject digest:
ba1d112f3537c86c9166a0eecc13595481d72a3484937d4d897082db21582dea - Sigstore transparency entry: 1237031725
- Sigstore integration time:
-
Permalink:
saemeon/pydygraphs@1cf70c622e16b51a319012b839936fdf18f1a057 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/saemeon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1cf70c622e16b51a319012b839936fdf18f1a057 -
Trigger Event:
release
-
Statement type: