10 Best Python Chart Libraries for Dashboards (2026)
Honest 2026 comparison of Python chart libraries for dashboards: Plotly, Matplotlib, Seaborn, Bokeh, Altair, Plotnine, ECharts (pyecharts), HoloViews, Plotly Express, and Streamlit built-ins. Code samples, decision tree, and when to switch.
.png)
Key Takeaways
- Plotly Express is the default for almost any interactive dashboard in 2026 - works natively in both Streamlit and Dash, ~5 lines for most chart types.
- Matplotlib still owns publication-quality static output (papers, PDFs, scientific reports). Use it there, not in dashboards.
- Altair / Vega-Altair is the right pick for declarative, faceted charts where you want to express the chart as a grammar-of-graphics specification.
- ECharts via
pyechartsis the only credible option for advanced visualisations Plotly doesn't do well - Sankey, geo maps, gauges, treemaps, calendar heatmaps. - Streamlit and Dash both have built-in charts that are good enough for KPIs and simple line/bar - reach for Plotly when the built-ins limit you, which is sooner than you'd expect.
- If your dashboard already uses 5–6 chart libraries, you're maintaining a small visualization platform yourself. That's the signal to look at embedded analytics for Python, which gives you 30–48 chart types out of the box.
There are roughly twenty Python chart libraries with active 2026 releases. Most fall into one of three buckets: interactive web-first (Plotly, Bokeh, Altair, ECharts), static publication-quality (Matplotlib, Seaborn, Plotnine), and dashboard-runtime built-ins (Streamlit, Dash, HoloViews). Picking wrong costs you weeks - Matplotlib is great for a journal paper and frustrating in a Streamlit dashboard; Plotly is great for a Streamlit dashboard and overkill for a one-off PDF.
This is the honest comparison: when each library wins, when it falls over, what the code looks like, and a decision tree so you don't have to read all 10 sections.
At a Glance
| Library | Type | Chart types | Interactivity | Best for | Watch out for |
|---|---|---|---|---|---|
Plotly (plotly.graph_objects) | Interactive web | 40+ | Hover, zoom, pan, click | General dashboards | SVG default melts past 10k points; switch to WebGL |
| Plotly Express | Interactive web (high-level) | 30+ | Inherits Plotly | Fast dashboard charts in 5 lines | Slightly less control than graph_objects |
| Matplotlib | Static | 40+ | None | Publication, PDFs, scientific reports | Bad fit for live dashboards |
| Seaborn | Static (statistical) | 25+ | None | Statistical exploration in notebooks | Built on Matplotlib - same dashboard caveat |
| Bokeh | Interactive web (canvas-first) | 30+ | Hover, zoom, linked brushing | Big-data dashboards (millions of points) | API verbosity; smaller community than Plotly |
| Altair / Vega-Altair | Interactive web (declarative) | 20+ | Hover, brush, link | Faceted, multi-view charts | 5,000-row default limit (configurable) |
| Plotnine | Static (ggplot2 port) | ggplot grammar | None | R / ggplot users on Python | Smaller ecosystem than ggplot2 itself |
ECharts (pyecharts) | Interactive web | 30+ unique | Rich (drill-down, animation) | Sankey, geo, gauges, calendar heatmaps | Heavier than Plotly; documentation mostly Chinese |
| HoloViews / hvPlot | Interactive (declarative wrapper) | Inherits Bokeh / Plotly / Matplotlib | Inherits backend | One-line charts on top of Bokeh / Datashader | Magical-feeling abstractions; learning curve for the model |
| Streamlit / Dash built-ins | Interactive web | ~6 (line, bar, area, scatter, map, plotly-passthrough) | Limited | KPI cards, quick-and-dirty charts | You'll outgrow them in week 2 |
Note on the "10": Plotly and Plotly Express share the same engine; some lists treat them as one library, some as two. I treat them as two because the API ergonomics are very different. The 10th slot here is "Streamlit / Dash built-ins" because most dashboards start there before reaching for Plotly.
1. Plotly (plotly.graph_objects)
The most widely used interactive Python chart library in 2026 - the default Plotly Dash uses internally and the most common chart engine inside Streamlit dashboards. Renders to interactive HTML+JS via the Plotly.js library.
pip install "plotly>=6"import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(x=df["month"], y=df["revenue"], mode="lines+markers", name="Revenue"))
fig.update_layout(title="Revenue by month", xaxis_title="Month", yaxis_title="Revenue ($)")
fig.show()- Strengths: rich interactivity (hover, zoom, pan, lasso select), 40+ chart types, perfect Streamlit and Dash integration, mature TypeScript/Python type stubs, can export to PNG/SVG/PDF for static use too.
- Weaknesses: SVG default rendering stalls past ~10,000 points (switch to
render_mode="webgl"for scatter/line); large bundle size in standalone HTML exports; learning curve onupdate_layoutif you want fine control. - Pick this if: you're building a dashboard in Streamlit or Dash. This is the default.
2. Plotly Express
A high-level wrapper around plotly.graph_objects. Most charts collapse to a single line. Use this for 80% of dashboard charts; drop down to graph_objects when you need fine-grained control.
import plotly.express as px
fig = px.line(df, x="month", y="revenue", title="Revenue by month", markers=True)- Strengths: 5-line dashboards, same renderer as Plotly so you can interleave Express and
graph_objectscalls, perfect Streamlit / Dash integration. - Weaknesses: less control over individual trace styling (you'll fall back to
fig.update_traces(...)afterpx.line(...)for anything custom). - Pick this if: you want a dashboard chart in 5 lines. (Then graduate to
graph_objectswhen you hit a limit.)
3. Matplotlib
The grandfather of Python visualisation, still the universal default for static output. If your "dashboard" is actually a weekly PDF or a journal figure, this is the right tool - and the wrong tool for an interactive web dashboard.
pip install "matplotlib>=3.10"import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(df["month"], df["revenue"], marker="o")
ax.set_title("Revenue by month")
ax.set_xlabel("Month"); ax.set_ylabel("Revenue ($)")
plt.savefig("revenue.png", dpi=200, bbox_inches="tight")- Strengths: 40+ chart types; produces print-quality static output; integrates with every notebook tool; battle-tested API.
- Weaknesses: no interactivity; verbose for "just give me a chart"; default styling looks dated (use
seaborn.set_style()to fix). - Pick this if: publication output, PDF reports, journal figures, anything destined for paper.
4. Seaborn
A statistical-charting layer on top of Matplotlib. Heatmaps, distribution plots, regression plots, pair plots - Seaborn makes them one line. Same static output as Matplotlib.
pip install "seaborn>=0.13"import seaborn as sns
sns.heatmap(df.corr(), annot=True, cmap="coolwarm")- Strengths: statistical primitives are first-class (
sns.regplot,sns.pairplot,sns.violinplot); much better default styling than raw Matplotlib; great for EDA in Jupyter. - Weaknesses: still static; struggles with very large datasets (uses Matplotlib underneath); not really a dashboard library.
- Pick this if: you're doing exploratory data analysis in a notebook or producing statistical figures for a report. Don't use it inside a Streamlit/Dash dashboard.
5. Bokeh
Interactive web library, canvas-first (so it scales to many more points than Plotly's default SVG). Less popular than Plotly in 2026 but still the right call for some big-data dashboards, especially when paired with Datashader.
pip install "bokeh>=3.9"from bokeh.plotting import figure, show
from bokeh.io import output_notebook
output_notebook()
p = figure(title="Revenue by month", x_axis_label="Month", y_axis_label="Revenue ($)")
p.line(df["month"], df["revenue"], line_width=2)
show(p)- Strengths: canvas rendering scales to millions of points (with Datashader); rich linked-brushing across multiple charts; integrates with Panel for full dashboards.
- Weaknesses: API verbosity (more boilerplate than Plotly); smaller community than Plotly in 2026; less idiomatic Streamlit integration (you can render Bokeh in Streamlit but Plotly is the smoother path).
- Pick this if: big-data dashboards (>1M points), or you're already using HoloViews / Panel.
6. Altair / Vega-Altair
Declarative grammar-of-graphics charts that compile to Vega-Lite specs. Great for faceted, multi-view dashboards where you want to express the chart as data + encoding rather than imperative drawing.
pip install "altair>=6"import altair as alt
chart = (
alt.Chart(df)
.mark_line(point=True)
.encode(x="month:T", y="revenue:Q")
.properties(title="Revenue by month")
)
chart.save("chart.html")- Strengths: truly declarative API (you describe what, not how); facets and small multiples are a one-liner; renders to standard Vega-Lite JSON which other tools can consume.
- Weaknesses: default 5,000-row limit (configurable via
alt.data_transformers.disable_max_rows()); fewer chart types than Plotly; smaller mindshare than the Plotly ecosystem. - Pick this if: you want declarative chart specs, faceted small-multiples dashboards, or the chart spec needs to be portable across languages (Vega-Lite is supported in JavaScript, R, Julia).
7. Plotnine
A Python port of R's ggplot2. Same grammar of graphics, same + operator composition. If you're an R / ggplot user moving to Python, this is the path of least resistance.
pip install "plotnine>=0.15"from plotnine import ggplot, aes, geom_line, geom_point, labs
(
ggplot(df, aes(x="month", y="revenue"))
+ geom_line()
+ geom_point()
+ labs(title="Revenue by month", x="Month", y="Revenue ($)")
)- Strengths: identical mental model to ggplot2; great composability; first-class facet wrapping.
- Weaknesses: static output (Matplotlib backend); smaller Python community than ggplot2 has on the R side, so when you search for "plotnine + X" you'll often find R answers; the underlying Matplotlib stack is what handles rendering, so very large datasets behave the same as Matplotlib.
- Pick this if: you're already fluent in
ggplot2and want to keep that grammar in Python. Otherwise, prefer Altair for declarative interactive charts.
8. ECharts (pyecharts)
A Python wrapper around Apache ECharts (originally Baidu, now Apache). The right answer when Plotly can't do what you need - Sankey diagrams, geo maps with smooth tile rendering, gauges, treemaps, calendar heatmaps, sunburst charts. pyecharts 2.1 (February 2026) was the first release to support ECharts 6.x and added a new Chord chart type.
pip install "pyecharts>=2.1"from pyecharts.charts import Sankey
from pyecharts import options as opts
nodes = [{"name": "Marketing"}, {"name": "Trial"}, {"name": "Customer"}, {"name": "Churn"}]
links = [
{"source": "Marketing", "target": "Trial", "value": 1000},
{"source": "Trial", "target": "Customer", "value": 200},
{"source": "Trial", "target": "Churn", "value": 800},
]
sankey = (
Sankey()
.add("Funnel", nodes, links, label_opts=opts.LabelOpts(position="right"))
.set_global_opts(title_opts=opts.TitleOpts(title="Conversion funnel"))
)
sankey.render("sankey.html")- Strengths: chart types you can't get elsewhere (Sankey, treemap, sunburst, calendar heatmap, geo, gauge); smooth animations; battle-tested at massive scale (used by Alibaba, Baidu).
- Weaknesses: larger bundle than Plotly; documentation skews Chinese (Apache ECharts docs are bilingual but
pyechartsexamples are mostly Chinese); rendering inside Streamlit needsstreamlit-echarts(third-party). - Pick this if: you need a chart type Plotly doesn't do well (Sankey, geo with custom tiles, calendar heatmaps).
9. HoloViews / hvPlot
A declarative wrapper that sits on top of Bokeh, Plotly, or Matplotlib - you describe the chart once and pick the renderer at deploy time. Pairs naturally with Panel (the HoloViz dashboard framework).
pip install "holoviews>=1.22" "hvplot>=0.12"import hvplot.pandas
df.hvplot.line(x="month", y="revenue", title="Revenue by month")- Strengths: one-line charts directly off pandas/dask DataFrames; renderer-agnostic (swap Bokeh ↔ Plotly without changing the chart code); first-class integration with Datashader for million-point charts; excellent Panel integration.
- Weaknesses: the abstraction has a learning curve (the magic is great when it works, less great when it doesn't); smaller community than Plotly; mostly used by the HoloViz / scientific-Python crowd.
- Pick this if: you're already in the HoloViz ecosystem (Bokeh, Datashader, Panel) or you want one-line charts with a renderer you can swap later.
10. Streamlit / Dash Built-In Charts
Both dashboard runtimes ship a handful of native charts that bypass any external library:
# Streamlit
st.line_chart(df.set_index("month")["revenue"])
st.bar_chart(df.set_index("region")["revenue"])
st.area_chart(...)
st.scatter_chart(...)
st.map(df_with_lat_lon)
# Dash has fewer built-in non-Plotly charts; in practice you use dcc.Graph + Plotly.- Strengths: zero dependency overhead; perfect integration with the framework; literally one line.
- Weaknesses: very limited customisation (no titles, axis labels, legends without dropping into Plotly); maximum ~6 chart types in Streamlit; almost nothing native in Dash.
- Pick this if: the chart is incidental (a tiny KPI sparkline, a quick visual sanity check). For anything that's the centrepiece of a dashboard, drop into Plotly.
Decision Tree
| Situation | Pick |
|---|---|
| "I'm building a Streamlit or Dash dashboard, give me the default" | Plotly Express |
| "Customer-facing publication-quality static report" | Matplotlib + Seaborn for styling |
| "Need a chart Plotly doesn't do well - Sankey, geo, calendar, gauge" | ECharts via pyecharts |
| "Big-data dashboard, millions of points" | Bokeh + Datashader (or HoloViews to wrap them) |
| "Faceted small-multiples that I want declarative" | Altair |
| "I'm an R / ggplot user moving to Python" | Plotnine |
| "Just a tiny sparkline next to a KPI number" | Streamlit / Dash built-ins |
| "I'm using six different chart libraries already" | Stop building. Embed analytics. |
When Chart Libraries Aren't Enough
Most dashboards start with one chart library (usually Plotly Express). They add a second when they need a Sankey (ECharts). They add a third when they need a million-point scatter (Bokeh + Datashader). At five or six chart libraries, you're maintaining a small in-house visualisation platform: bundle size goes up, a new chart type means picking which library does it cleanest, theming has to be reapplied per library, and the test surface explodes.
That's the moment to look at embedded analytics. A platform like Databrain, Metabase, or Cube ships 30–48 prebuilt chart types with consistent theming, drill-downs, and exports - none of which you have to maintain. The integration is 1–5 days from a Python backend (FastAPI, Django, or Flask). If your dashboard is internal, this trade-off rarely makes sense - keep stacking chart libraries. If your dashboard is customer-facing inside a SaaS product, it almost always does. See Embedded Analytics in Python for the FastAPI guest-token pattern.
Next Steps
- Build a dashboard from scratch: Python Dashboard: The Complete 2026 Guide - runnable Streamlit + Dash + Gradio walkthroughs that all use Plotly Express
- Streamlit vs Dash, head-to-head: Streamlit vs Dash in 2026 - same dashboard built in both
- For customer-facing multi-tenant analytics: Embedded Analytics in Python - when 30–48 chart types out of the box beats stacking libraries
- Cross-language reference: 10 Best React Chart Libraries for Interactive Dashboards - the JavaScript-side equivalent for teams that build dashboards in both Python and React
- Working code: python-tutorial-scratch - a runnable Streamlit dashboard using Plotly Express, no fluff
Covers Plotly 6.x, Matplotlib 3.10, Seaborn 0.13.2, Bokeh 3.9, Altair 6.x, Plotnine 0.15, pyecharts 2.1 (with ECharts 6.x), HoloViews 1.22, hvPlot 0.12, Python 3.13. Last updated April 2026.
Rahul Pattamatta is co-founder of Databrain, an embedded analytics platform for SaaS.
Frequently Asked Questions
What's the most popular Python chart library in 2026?
By installs and Stack Overflow questions, Matplotlib is still #1 (because of its historical install base in scientific Python). For new dashboard work in 2026, Plotly is the most popular - it's the default chart engine inside both Streamlit and Dash, and Plotly Express specifically is the most common high-level chart API in production Python dashboards.
Plotly vs Matplotlib for dashboards?
Plotly. Matplotlib is excellent for static publication output (PDFs, papers, journal figures) and frustrating in dashboards because it has no interactivity. If you're building a Streamlit or Dash dashboard, default to Plotly Express; reserve Matplotlib for the static-export side of your data pipeline.
Is Seaborn good for dashboards?
No - Seaborn is built on Matplotlib and produces static charts. It's excellent for exploratory data analysis in Jupyter and statistical figures for reports. For dashboards, use Plotly Express; the chart types overlap heavily, and Plotly gives you interactivity.
Does Streamlit need a separate chart library?
Streamlit's built-in charts (st.line_chart, st.bar_chart, st.area_chart, st.scatter_chart, st.map) are good for KPI sparklines and quick exploratory charts. Past that, drop into Plotly via st.plotly_chart(fig) - most production Streamlit dashboards use Plotly for the main charts and built-ins for sparklines.
Can I use D3 from Python?
Indirectly - most "use D3 from Python" libraries (mpld3, plotly.js, bokeh) wrap a JavaScript layer that compiles to D3 under the hood. If you want true D3-level control, write the D3 in JavaScript and embed it via st.components.v1.html (Streamlit) or dcc.Graph with a custom JSON schema (Dash). For most cases, Plotly's API gives you 90% of D3's expressiveness with 10% of the code.




