Skip to main content

A matplotlib-style fluent builder API for Apache ECharts in Python, Jupyter Notebooks, and Streamlit.

Project description

Apache ECharts

echartsy

Interactive charts in Python — the matplotlib workflow, the ECharts experience.

PyPI version Python versions License Stars Issues

Build publication-quality interactive charts with a familiar
fig = figure()fig.bar()fig.show() workflow.
Works everywhere: Jupyter · Streamlit · standalone scripts


Why echartsy?

  • Feels like matplotlib — If you know plt.figure() / plt.show(), you already know 90% of the API. No JSON wrangling, no JavaScript.
  • Interactive out of the box — Every chart ships with tooltips, legend toggling, zoom, and a built-in export toolbox. Zero configuration needed.
  • One library, three engines — Write once, render in Jupyter notebooks, Streamlit apps, or plain Python scripts that pop open a browser.
  • Composable & animated — Layer pies on bar charts, build dual-axis dashboards, or animate any chart across time with TimelineFigure.

Installation

pip install echartsy

Need extras?

pip install echartsy[jupyter]     # Jupyter Notebook / JupyterLab
pip install echartsy[streamlit]   # Streamlit apps
pip install echartsy[scipy]       # KDE density plots
pip install echartsy[all]         # Everything

Requirements: Python 3.9+ · pandas ≥ 1.5 · numpy ≥ 1.23


Quick Start

import pandas as pd
import echartsy as ec

ec.config(engine="jupyter")          # or "python" / "streamlit"

df = pd.DataFrame({
    "Fruit": ["Apples", "Bananas", "Cherries", "Dates", "Elderberries"],
    "Sales": [120, 95, 78, 42, 63],
})

fig = ec.figure()
fig.bar(df, x="Fruit", y="Sales", gradient=True, labels=True)
fig.title("Fruit Sales")
fig.show()

Three lines from DataFrame to interactive chart.

Quick Start — Bar Chart


Gallery

Cartesian Charts

Bar + Pie Overlay

Bar + Pie Overlay

fig = ec.figure(height="500px")
fig.bar(df, x="Dept", y="Budget",
        gradient=True, labels=True)
fig.pie(df, names="Dept", values="Budget",
        center=["82%","25%"],
        radius=["18%","28%"])
fig.show()

Smooth Line

Line Chart

fig = ec.figure()
fig.plot(df, x="Month", y="Sales",
         smooth=True, area=True)
fig.show()

Scatter Plot

Scatter Plot

fig = ec.figure()
fig.scatter(df, x="Height", y="Weight",
            color="Gender", size="Age")
fig.show()

Grouped Bar

Grouped Bar

fig = ec.figure()
fig.bar(df, x="Quarter", y="Revenue",
        hue="Region")
fig.show()

Stacked Bar

Stacked Bar

fig = ec.figure()
fig.bar(df, x="Month", y="Revenue",
        hue="Product", stack=True)
fig.show()

Histogram

Histogram

fig = ec.figure()
fig.hist(df, column="Score", bins=20)
fig.show()

Area Chart

Area Chart

fig = ec.figure()
fig.plot(df, x="Month", y="Users",
         area=True, smooth=True)
fig.show()

Horizontal Bar

Horizontal Bar

fig = ec.figure()
fig.bar(df, x="Country", y="Population",
        orient="h")
fig.show()

Dual Axis: Bar + Line

Dual Axis

fig = ec.figure()
fig.bar(df, x="Month", y="Revenue")
fig.plot(df, x="Month", y="Growth",
         smooth=True, axis=1)
fig.ylabel("Revenue ($K)")
fig.ylabel_right("Growth %")
fig.show()

Gradient Bars

Gradient Bars

fig = ec.figure()
fig.bar(df, x="City", y="Temp",
        gradient=True,
        gradient_colors=["#83bff6","#188df0"])
fig.show()

Multi-Line with Area

Multi-Line

fig = ec.figure()
fig.plot(df, x="Month", y="Value",
         hue="Series", smooth=True,
         area=True)
fig.show()

Boxplot

Boxplot

fig = ec.figure()
fig.boxplot(df, x="Department", y="Salary")
fig.show()

Standalone Charts

Donut / Pie

Donut Chart

fig = ec.figure()
fig.pie(df, names="Browser", values="Share",
        inner_radius="40%")
fig.show()

Radar

Radar Chart

fig = ec.figure()
fig.radar(indicators, data,
          series_names=["Warrior","Mage"])
fig.show()

Heatmap

Heatmap

fig = ec.figure()
fig.heatmap(df, x="Day", y="Hour",
            value="Count")
fig.show()

Funnel

Funnel

fig = ec.figure()
fig.funnel(df, names="Stage", values="Count")
fig.show()

Treemap

Treemap

fig = ec.figure()
fig.treemap(df,
    path=["Category","SubCat"],
    value="Sales")
fig.show()

Sankey Diagram

Sankey Diagram

fig = ec.figure()
fig.sankey(df,
    levels=["Source","Channel","Outcome"],
    value="Users")
fig.show()

Composite & Dashboard Charts

Bar + Pie (Dark)

Composite Dark

Triple Composite

Triple Composite

KPI Dashboard

KPI Dashboard

Stacked + Trend + Pie

Full Dashboard

Side-by-Side Pies

Side-by-Side Pies

Dark Theme

Dark Theme

Every chart is fully interactive — hover for tooltips, click legend items to toggle series, use the toolbox to export. Open the HTML demos in assets/ for the live experience, or run python generate_demos.py yourself.


Supported Chart Types

Category Method Description
Line fig.plot() Smooth/straight lines, multi-series via hue, optional filled area
Bar fig.bar() Vertical/horizontal, grouped (hue), stacked, gradient fills
Scatter fig.scatter() Color and size encoding, numeric axes
Histogram fig.hist() Auto-binned frequency distribution
Boxplot fig.boxplot() Five-number statistical summary
KDE fig.kde() Kernel density estimation (requires scipy)
Pie / Donut fig.pie() Pie, donut (inner_radius), rose charts, side-by-side multiples
Radar fig.radar() Multi-indicator polygon charts
Heatmap fig.heatmap() Matrix visualisation with colour mapping
Sankey fig.sankey() Multi-level flow diagrams
Treemap fig.treemap() Hierarchical area charts
Funnel fig.funnel() Stage-based conversion funnels

Rendering Engines

echartsy writes your chart once; ec.config() controls where it renders.

Engine Use case Install
"python" Standalone scripts — opens the default browser No extra deps
"jupyter" Jupyter Notebook / JupyterLab inline widgets pip install echartsy[jupyter]
"streamlit" Streamlit applications pip install echartsy[streamlit]
ec.config(engine="jupyter")

Adaptive Dark Mode

Charts automatically respond to the user's OS or browser prefers-color-scheme setting.

ec.config(engine="jupyter", adaptive="auto")     # auto-detect (default)
ec.config(engine="jupyter", adaptive="dark")     # force dark
ec.config(engine="jupyter", adaptive="light")    # force light

Style Presets & Palettes

Apply a pre-built visual theme in one argument:

fig = ec.figure(style=ec.StylePreset.CLINICAL)         # Clean defaults
fig = ec.figure(style=ec.StylePreset.DASHBOARD_DARK)    # Dark background
fig = ec.figure(style=ec.StylePreset.KPI_REPORT)        # Warm rusty tones
fig = ec.figure(style=ec.StylePreset.MINIMAL)            # Minimal & light

Or set a custom palette at any time:

fig.palette(["#667eea", "#764ba2", "#f093fb", "#f5576c", "#4facfe"])
fig.palette(ec.PALETTE_RUSTY)
fig.palette(ec.PALETTE_CLINICAL)

Build your own StylePreset for full control over fonts, grid lines, tooltip style, and more:

my_style = ec.StylePreset(
    palette=("#264653", "#2a9d8f", "#e9c46a", "#f4a261", "#e76f51"),
    bg="#fefae0",
    font_family="Georgia",
    title_font_size=20,
)
fig = ec.figure(style=my_style)

Emphasis (Hover Highlighting)

Control what happens when users hover over chart elements — highlight, dim, scale, or restyle — using typed Python dataclasses instead of raw dicts.

Every chart method accepts an optional emphasis parameter with a chart-specific type:

Chart method Emphasis class Extra fields
bar(), hist(), boxplot(), heatmap() Emphasis
plot(), kde() LineEmphasis line_style, area_style, end_label
scatter() ScatterEmphasis scale
pie() PieEmphasis scale, scale_size, label_line
radar() RadarEmphasis line_style, area_style
sankey() SankeyEmphasis line_style, focus supports "adjacency"
funnel() FunnelEmphasis label_line
treemap() TreemapEmphasis label_line, upper_label

All classes share these common fields: disabled, focus ("none" / "self" / "series"), blur_scope, item_style, and label.

from echartsy import Figure, Emphasis, ItemStyle

# Highlight the hovered series, dim everything else
fig = Figure()
fig.bar(df, x="Month", y="Revenue", hue="Region",
        emphasis=Emphasis(
            focus="series",
            item_style=ItemStyle(shadow_blur=10, shadow_color="rgba(0,0,0,0.3)"),
        ))
fig.show()
from echartsy import Figure, LineEmphasis, LineStyle, LabelStyle

# Bold the hovered line and show value labels
fig = Figure()
fig.plot(df, x="Date", y="Price", hue="Stock",
         emphasis=LineEmphasis(
             focus="series",
             line_style=LineStyle(width=4),
             label=LabelStyle(show=True, formatter="{c}"),
         ))
fig.show()
from echartsy import Figure, PieEmphasis, ItemStyle

# Scale and shadow on hover
fig = Figure()
fig.pie(df, names="Category", values="Amount",
        emphasis=PieEmphasis(
            scale=True, scale_size=15,
            item_style=ItemStyle(shadow_blur=20),
        ))
fig.show()

When emphasis is omitted, each chart keeps its existing default behaviour (backward compatible).


Composite Charts

Overlay pies on cartesian charts, or combine bar + line on dual axes — all on one figure.

fig = ec.figure(height="550px")

# Primary axis: bars
fig.bar(df, x="Month", y="Revenue", labels=True, border_radius=4)

# Secondary axis: trend line
fig.plot(df, x="Month", y="Growth", smooth=True, axis=1, line_width=3)

# Inset pie
fig.pie(df_mix, names="Plan", values="Share",
        center=["25%", "32%"], radius=["15%", "25%"])

fig.ylabel("Revenue ($K)")
fig.ylabel_right("Growth %")
fig.legend(top=40, left=350)
fig.show()

Timeline Animations

Animate any chart across a time dimension with TimelineFigure. It mirrors the Figure API; every series method gains one extra parameter: time_col.

fig = ec.TimelineFigure(height="500px", interval=1.5)
fig.bar(df, x="Country", y="GDP", time_col="Year", labels=True)
fig.title("GDP by Country")
fig.ylabel("GDP (Trillion USD)")
fig.legend(top=30)
fig.show()

Timeline Animation

TimelineFigure features:

Feature API
Playback control TimelineFigure(interval=2.0, autoplay=True, loop=True)
Adjust after creation fig.playback(interval=1.0, rewind=True)
Smart frame sorting Parses years, quarters (Q1 2024), months (Jan 2024), ISO dates, fiscal years
Supported series bar(), plot(), scatter(), pie()
Diagnose format ec.detect_time_format(df["Year"])

Chart Configuration Reference

Every Figure and TimelineFigure supports these configuration methods:

# Titles
fig.title("Main Title", subtitle="Sub-title")

# Axes
fig.xlabel("X Label", rotate=30)
fig.ylabel("Y Label")
fig.ylabel_right("Secondary Y")
fig.xlim(0, 100)
fig.ylim(0, 500)

# Layout
fig.legend(orient="vertical", left="right", top=40)
fig.margins(left=100, right=120, top=40)
fig.grid(show=True)

# Interactivity
fig.datazoom(start=0, end=80)
fig.toolbox(download=True, zoom=True)
fig.tooltip(trigger="axis")

# Export
fig.save(name="my_chart", fmt="png", dpi=3)
fig.to_html("my_chart.html")

# Palette
fig.palette(["#5470C6", "#91CC75", "#FAC858"])

Exporting

# Standalone HTML file (fully interactive, no server needed)
fig.to_html("report.html")

# Raw ECharts option dict (for debugging or custom renderers)
option = fig.to_option()

API at a Glance

ec.config(engine, adaptive="auto")

Set the global rendering engine ("python", "jupyter", "streamlit") and theme adaptation mode ("auto", "light", "dark").

ec.figure(**kwargs) / ec.Figure(**kwargs)

Create a chart canvas. Key keyword arguments:

Parameter Default Description
height "400px" CSS height of the chart container
width None CSS width (defaults to full container)
renderer "canvas" "canvas" or "svg"
style StylePreset.CLINICAL A StylePreset instance

ec.TimelineFigure(**kwargs) / ec.timeline_figure(**kwargs)

Same as Figure but adds timeline animation. Extra parameters:

Parameter Default Description
interval 2.0 Seconds between animation frames
autoplay True Start playing automatically
loop True Loop back to the first frame

ec.StylePreset

Frozen dataclass bundling visual defaults: palette, bg, font_family, title_font_size, axis_label_font_size, grid_line_color, and more.

ec.Emphasis, ec.LineEmphasis, ec.PieEmphasis, ...

Frozen dataclasses configuring hover-highlight behaviour per series. Common fields: disabled, focus, blur_scope, item_style (ItemStyle), label (LabelStyle). Chart-specific subclasses add fields like line_style, area_style, scale, scale_size, and label_line. See the Emphasis section for the full mapping.

Sub-style dataclasses

Class Key fields
ec.ItemStyle color, border_color, border_width, border_radius, shadow_blur, shadow_color, opacity
ec.LabelStyle show, position, formatter, font_size, font_weight, color
ec.LineStyle color, width, type ("solid" / "dashed" / "dotted"), shadow_blur, opacity
ec.AreaStyle color, opacity
ec.LabelLineStyle show, length, length2

ec.detect_time_format(series)

Diagnostic helper that inspects a pandas Series and reports how well TimelineFigure will parse its values.


Generating Showcase Images

To regenerate the demo screenshots shown above:

# 1. Generate the interactive HTML demos
python generate_demos.py

# 2. Capture PNG screenshots (requires Playwright)
pip install playwright && playwright install chromium
python capture_screenshots.py

Contributing

Contributions, bug reports, and feature requests are welcome. Please open an issue or submit a pull request on GitHub.

License

MIT — Jigar, 2026

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

echartsy-0.2.0.tar.gz (48.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

echartsy-0.2.0-py3-none-any.whl (47.1 kB view details)

Uploaded Python 3

File details

Details for the file echartsy-0.2.0.tar.gz.

File metadata

  • Download URL: echartsy-0.2.0.tar.gz
  • Upload date:
  • Size: 48.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for echartsy-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5daec12c8e6d0b41ecdf0a9a62dbe063e4cca94803b59eb3dcf54fbdfdfabf6b
MD5 0503b4a369a9d9430b608f3bd0b0e6c1
BLAKE2b-256 f53a49130739924cd018887da864b125c6ef2846b912770a11af76624a0bc4e9

See more details on using hashes here.

File details

Details for the file echartsy-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: echartsy-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 47.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for echartsy-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3afae161686ff379a88f37257c0dd2f94ea4c1f6c19b297af1fc080975ef39c2
MD5 5afbd210d118ec8aeb79c888872d90e9
BLAKE2b-256 32e6b6d8f3d2909a23f6064d3787b56c3bfeae1a1de6f51f04a5c2039bce768c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page