Skip to main content

logo

Data visualization package, simple to use, highly customizable

Test Package Package Index Supported Python Versions License Changelog

Documentation · How-to Guides · API Reference · Source


The datachart package is a python package for creating data visualizations, built on top of matplotlib. It is designed to be simple to use and highly customizable, i.e. it is easy to change the look and feel of the charts.

Features:

  • Charts. Chart types for trends, comparisons, distributions, relationships, and flows — each created with a single function call from plain lists of dicts. See Charts.
  • Composition. Combine rendered charts with Panel (overlay charts on a single plot, with optional dual y-axes) and Grid (arrange charts in a grid; grids nest). See Composition.
  • Themes & configuration. Predefined themes, each named for its visual trait, plus a global config for tweaking any style attribute — per-chart style overrides included. See Themes.

Quick start

pip install datachart   # or: uv add datachart

Every chart takes a list of series, each a list of dicts. Set a theme once and every chart follows it:

from datachart.charts import LineChart
from datachart.config import config
from datachart.constants import THEME
from datachart.utils import save_figure

config.set_theme(THEME.INK)

months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"]
signups = [420, 465, 430, 510, 560, 545, 610]
churned = [380, 400, 440, 435, 480, 520, 550]

figure = LineChart(
    [
        [{"x": x, "y": y} for x, y in enumerate(signups)],
        [{"x": x, "y": y} for x, y in enumerate(churned)],
    ],
    title="Monthly signups vs. churn",
    subtitle=["Signups", "Churned"],
    xlabel="Month",
    ylabel="Users",
    xticks=list(range(len(months))),
    xticklabels=months,
    show_legend=True,
)
save_figure(figure, "line.png")

Quick start line chart

figure is a plain matplotlib Figure, so anything matplotlib can do with it still works.

Charts

Every chart is a single function call taking plain lists of dicts, and every function accepts a list of series to overlay or a subplots=True flag to split them apart. The dict keys per chart are listed in each guide.

Family Charts Use for
Trends LineChart, StackedAreaChart, BumpChart values over an ordered axis; area for part-of-whole over time; rank over time
Comparisons BarChart, PyramidChart, RadialChart, CalendarHeatmap, GanttChart, DumbbellChart category totals, paired populations, cyclic/periodic values, daily rhythm, schedules, before/after change
Distributions Histogram, BoxPlot, ViolinPlot, SwarmPlot, RaincloudPlot, RidgelinePlot shape and spread of one variable, per group; many groups stacked in ridges
Relationships ScatterChart, Heatmap, ContourChart, HexbinChart, ParallelCoords, NetworkChart, ScatterMatrix two-variable correlation, matrices, dense 2-D density, many dimensions, who is linked to whom, every pair at once
Flows SankeyChart quantities moving between stages
Proportions Treemap how a whole splits into parts, grouped up to four levels deep

Composition

Rendered figures compose. Grid arranges them in a grid (nested lists define rows; grids nest), and Panel overlays charts on one plot, with an optional secondary y-axis. Four chart types, one theme, one grid — with a Panel in the last cell:

import numpy as np

from datachart.charts import BarChart, Histogram, LineChart, ScatterChart
from datachart.config import config
from datachart.constants import LEGEND_LOCATION, THEME
from datachart.utils import Grid, Panel, save_figure

config.set_theme(THEME.INK)
rng = np.random.default_rng(0)

line = LineChart(
    [[{"x": x, "y": 50 + a * np.sin(x / 3) + x} for x in range(21)] for a in (20, 12, 5)],
    title="Line", subtitle=["Run 1", "Run 2", "Run 3"], show_legend=True,
)
bars = BarChart(
    [[{"label": f"Bench {b}", "y": y} for b, y in zip("ABCD", ys)]
     for ys in ([66, 59, 77, 83], [65, 58, 78, 82])],
    title="Grouped bar", subtitle=["Model A", "Model B"], show_legend=True,
)
scatter = ScatterChart(
    [[{"x": x, "y": y} for x, y in zip(rng.normal(cx, 1.2, 60), rng.normal(cy, 1, 60))]
     for cx, cy in ((3, 4), (7, 7), (10, 3))],
    title="Scatter", subtitle=["C1", "C2", "C3"], show_legend=True,
)

# Panel overlays figures on one axes; the line gets its own y-axis on the right
samples = np.sort(rng.normal(55, 12, 500))
hist = Histogram([{"x": x} for x in samples], subtitle="Count")
cdf = LineChart(
    [{"x": x, "y": 100 * i / len(samples)} for i, x in enumerate(samples, 1)],
    subtitle="Cumulative %",
)
config.update_config({"plot_legend_location": LEGEND_LOCATION.UPPER_LEFT})
overlay = Panel(
    [hist, cdf], title="Histogram + line", ylabel_right="%",
    auto_secondary_axis=1, show_legend=True,
)

# Grid arranges figures in cells; nested lists define the rows
figure = Grid([[line, bars], [scatter, overlay]], title="INK theme")
save_figure(figure, "grid.png")

Line, grouped bar, scatter, and a histogram+line panel in a 2x2 grid, INK theme

Themes

Predefined themes, applied with config.set_theme(THEME.<NAME>). Any attribute can then be tweaked globally via config.update_config(...) or per chart via the style argument — see the themes, config, and theme gallery guides.

The same grouped bar chart across the predefined themes

More examples on how to use the datachart package are available on the official How-to Guides.

Install

Requires python 3.10 or higher.

pip install -U datachart

With uv:

uv add datachart

For zoom, pan, and hover-to-inspect via figure.show(interactive=True), add the interactive extra: pip install "datachart[interactive]".

Using with LLMs

The documentation is available in LLM-friendly formats:

You can also connect your AI assistant directly:

  • Context7 — up-to-date, version-aware docs for AI coding assistants
  • GitMCP — an MCP server serving this repository's documentation

Contributing

Bug reports, feature requests, and pull requests are welcome — open an issue to report a problem or propose a chart, theme, or option you are missing.

To work on the package locally:

git clone https://github.com/eriknovak/datachart.git
cd datachart
uv sync --group dev                  # package + dev dependencies
python -m unittest discover test     # unit tests
pytest                               # documentation notebooks
mkdocs serve                         # docs at http://127.0.0.1:8000

Code is formatted with black; the pre-commit hook runs it for you.

Metadata

Release files for datachart 0.10.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for datachart 0.10.2
File Size Uploaded
datachart-0.10.2.tar.gz 847.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for datachart 0.10.2
File Interpreter ABI Platform
datachart-0.10.2-py3-none-any.whl Python 3 none any Details

Total release size: 1.6 MB

Release files / datachart-0.10.2.tar.gz

Download URL datachart-0.10.2.tar.gz
Size 847.5 kB
Tags Source
SHA-256 checksum
How to use checksums
9d475a1fa2cfcfa7b637a537c384757ab201d099dd5263b310d08da5b5ed2863
BLAKE2b-256 checksum
How to use checksums
1c6232138daefa3d3f845ca8498e96714288a40e5aba98b45a7d5ca77ba24fd9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / datachart-0.10.2-py3-none-any.whl

Download URL datachart-0.10.2-py3-none-any.whl
Size 748.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1b45cb1230efcb1fb427ce729380998ce9ae729ae43d8d741909a1d5078aaf1c
BLAKE2b-256 checksum
How to use checksums
1a034c87309fcde859e713dc1507f4bd5d86c6c35a64a7e54c235fef31e5e078
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

1.0.0

2 release files

This release

0.10.2 This release

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.0

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page