Library / SDK
pyecharts/pyecharts avatar
pyecharts/pyecharts

pyecharts chains Python calls into ECharts and writes out an HTML file

🎨 Python Echarts Plotting Library

15,779 stars2,833 forksPythonMIT

At a glance

What is it?
pyecharts is an MIT licensed Python wrapper around Apache ECharts that supports chained calls, more than 30 chart types and over 400 map files. Rendering produces an HTML file rather than an image, which means a browser driver and one of three optional snapshot backends stand between you and a PNG. The metadata also carries two spellings of the same extra dependency, and the documented contributor setup and the Makefile use different tools.
Who is it for?
pyecharts earns its place when you want interactive HTML charts from Python data structures with configuration options set in Python rather than in JavaScript, and when shipping an HTML file is acceptable. It is the wrong tool when you need a PNG in a non-browser environment without adding a headless driver, and pinning 0.5.x is a mistake since that branch is declared unmaintained.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 19 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • pyecharts/pyecharts15,779 ★ · +8
Star history
Repository2026-09-212026-11-14
pyecharts/pyecharts15.8k15.8k

8 Stars in the last 54 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The notebook and web framework sections are headings with nothing under them

The feature list claims support for Jupyter Notebook, JupyterLab and marimo, plus easy integration with Flask, Sanic and Django. Then the usage section repeats those claims as empty headings: a Notebook 环境 heading, a Jupyter Notebook heading, a JupyterLab heading and a Web 框架 heading, each with no content beneath it.

So the compatibility is asserted and the demonstration is missing. The part of the README a new user actually needs, a notebook cell or a Flask route showing how a rendered chart reaches a page, is precisely the part that is blank.

The consequence is that this README cannot get you started for the environments it advertises. You have to leave for the documentation site, where the Chinese version lives at pyecharts.org/#/zh-cn/, the English at pyecharts.org/#/en-us/, and the worked examples at gallery.pyecharts.org. Note also that the README itself is in Chinese and links to a separate README.en.md, so the English reader is already one hop behind before any of that.

Judge this project on the documentation site rather than the repository front page.

The images extra is spelled two different ways in the two metadata files

There are two sources of package metadata, and they disagree on one extra. In pyproject.toml the optional dependencies read:

toml
selenium = ["snapshot-selenium"]
phantomjs = ["snapshot-phantomjs"]
pyppeteer = ["snapshot-pyppeteer"]
images = ["Pillow"]

In setup.py the equivalent dictionary spells the same entry differently, listing images as PIL rather than Pillow. Those are the old and new names for the same library, and only one of them is the current distribution name.

This is a small thing that only matters at the moment it bites. If your installer reads the pyproject metadata you get a working Pillow install, and if anything resolves through the legacy setup.py path the name differs. Either way the consequence is the same: the images extra, the one you need to turn a chart into a picture, is the entry with inconsistent spelling.

If you are pulling that extra, install Pillow explicitly rather than trusting the extra to resolve, and check which metadata file your build frontend actually consumed.

Publishing runs as a local setup.py command that shells out three times

Releasing is a custom Command class inside setup.py called UploadCommand, and its run method is a sequence of os.system calls with no exit status checks between them. The order is: remove the previous dist, build and egg-info directories, run setup.py sdist bdist_wheel, run twine upload dist/*, then run git tag -a with the version interpolated.

Three things follow. The tag is created after the upload rather than before, so a failure between the two steps leaves a package published to PyPI with no matching tag in the repository. Because os.system return values are not inspected, a failed twine upload does not stop the git tag from being attempted. And this is a local script rather than a pipeline, so the release depends on one maintainer having a working local environment.

For a user this is background, but it explains something you will observe: the version in your environment comes from setuptools_scm, which is configured with a guess-next-dev version scheme and a dirty-tag local scheme, and declared dynamic in pyproject.toml. That is why the installed version can look like a development build rather than one of the tagged releases.

Version metadata lives in two places, and the source install path is a deprecated command

pyproject.toml declares dynamic = ["version"] and hands version control to setuptools_scm, reading it from git rather than storing it. setup.py still exists and takes a different route, opening pyecharts/_version.py and exec'ing the contents into a dict to recover __version__.

So there are two files that can answer what version this is, and they answer from different sources. Neither is wrong on its own, which is the problem: a mismatch between what git describes and what the generated module records is not something either file would flag.

The documented source installation path then runs the command that has been deprecated for years:

shell
$ git clone https://github.com/pyecharts/pyecharts.git
$ cd pyecharts
$ pip install -r requirements.txt
$ python setup.py install

Against a modern setuptools that command warns or fails, and the project now builds with uv, since the Makefile build target is simply uv build. If you are installing from source, use a build frontend rather than replaying these four lines, and expect the README to be behind the Makefile.

Charts render to an HTML file, and pictures need a browser you have to bring

The basic usage path ends in a single call. You build a chart with add_xaxis, add_yaxis and set_global_opts, then call render(), and the output is an HTML file. The README also shows the same chart written without chaining, one method per line, for developers who prefer it.

Producing an image is a different pipeline with different dependencies. The example imports snapshot_selenium as driver and make_snapshot from pyecharts.render, and there are three separate snapshot backends available as extras: selenium, phantomjs and pyppeteer, each pulling its own package. A fourth extra, images, adds Pillow.

That is the practical limit to plan around. If your charts are going into a notebook or a web page, render() is enough and nothing else is needed. If they need to be PNG files in a report or an email, you are now running a headless browser, and you have three backends to choose between rather than one documented default.

Pinning 0.5.x installs a branch the project has declared unmaintained

The versioning section is explicit that v0.5.x and V1 are not compatible, and that V1 is an entirely new version. The 0.5.x line supported Python 2.7 and 3.4 or later, and the development team decided that 0.5.x would no longer be maintained. Its code lives on a branch named 05x and its documentation is hosted separately at 05x-docs.pyecharts.org.

The pip instructions still offer that path:

shell
# 安装 v1 以上版本
$ pip install pyecharts -U

# 如果需要安装 0.5.11 版本的开发者,可以使用
# pip install pyecharts==0.5.11

So an unmaintained, incompatible line remains an advertised install target. If you pin 0.5.11 to avoid an upgrade, you have chosen a branch that will not receive fixes, and you have chosen it against documentation hosted at a different domain than the current one.

Both current lines, V1 and V2, require Python 3.7 or later, and V2 is the one that renders against ECharts 5.4.1 or later. Go to V2 unless you have a specific reason not to.

Two contributor toolchains are documented, uv in the Makefile and pip in the guide

The code quality section tells you to install test requirements and run make:

shell
$ pip install -r test/requirements.txt
$ make

The Makefile itself no longer works that way. The test target runs uv run pytest -v with coverage configured against pyproject.toml, the build target is uv build, and lint runs uv run flake8 with a max line length of 89 and F401 and F824 ignored. pyproject.toml carries a [tool.uv] section with dev dependencies including pytest, pytest-cov, coverage, flake8, mccabe, codecov, nose2 and Pillow.

Meanwhile the contributing guide asks pull requests to be formatted with black and isort, installed from requirements-dev.txt, a file that still exists at the top level. So there are two described ways to set up: a pip and requirements-dev.txt path from the contributing guide, and a uv path from the Makefile and pyproject.

For a user this hardly matters. For anyone sending a pull request it does, because a test run that fails on a formatting or environment difference costs you a review cycle. Read the Makefile rather than the guide, and run make test before you push.

Editorial conclusion

pyecharts earns its place when you want interactive HTML charts from Python data structures with configuration options set in Python rather than in JavaScript, and when shipping an HTML file is acceptable. It is the wrong tool when you need a PNG in a non-browser environment without adding a headless driver, and pinning 0.5.x is a mistake since that branch is declared unmaintained. Before you rely on it, check which of the two metadata files your installer reads, and render one chart in CI so a snapshot backend problem surfaces early.

Frequently asked questions

What does pyecharts produce, an HTML file or an image?

Both, through different paths. Calling render() on a chart writes an HTML file, which is the basic usage. To get an image you use make_snapshot from pyecharts.render with one of three snapshot backends available as extras, selenium, phantomjs or pyppeteer, plus an images extra that adds Pillow.

Is pyecharts still maintained?

The repository is not archived and its default branch last took a push on 2026-10-26, after the most recent release v2.1.0 dated 2026-02-10. The 0.5.x line is explicitly declared no longer maintained, with its code on a separate branch and its own documentation domain.

How do I install pyecharts from source?

Clone the repository, install the three runtime dependencies from requirements.txt, which are jinja2, prettytable and simplejson, then build. The README documents python setup.py install, which is deprecated, while the Makefile uses uv build instead. The 0.5.11 version requires cloning the separate branch instead.

Which Python versions does pyecharts support?

The current V1 and V2 lines require Python 3.7 or later, and pyproject.toml declares requires-python as >=3.7 with classifiers listing 3.7 through 3.14. The older 0.5.x line supported Python 2.7 and 3.4 or later but is no longer maintained.

Official sources

  1. License: MIT
  2. Project website
  3. pyecharts/pyecharts on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pyecharts-pyecharts.svg)](https://hysenlabs.com/projects/pyecharts-pyecharts)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/pyecharts-pyecharts.svg)](https://hysenlabs.com/projects/pyecharts-pyecharts)

Was this useful?