{"id":27995212,"url":"https://github.com/sunhailin-leo/pyantv","last_synced_at":"2026-04-23T21:02:02.276Z","repository":{"id":281762475,"uuid":"244527047","full_name":"sunhailin-Leo/pyantv","owner":"sunhailin-Leo","description":"Python ❤️ AntV (https://antv.antgroup.com/) = pyantv","archived":false,"fork":false,"pushed_at":"2026-04-23T14:11:17.000Z","size":657,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-04-23T14:31:59.091Z","etag":null,"topics":["antv","antv-g2","plotting","python","visualization"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sunhailin-Leo.png","metadata":{"files":{"readme":"README.en.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-03-03T02:53:47.000Z","updated_at":"2026-01-17T14:21:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"f8b6c2a9-ce05-4c2b-9717-8d4c3e04237f","html_url":"https://github.com/sunhailin-Leo/pyantv","commit_stats":null,"previous_names":["sunhailin-leo/pyantv"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/sunhailin-Leo/pyantv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunhailin-Leo%2Fpyantv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunhailin-Leo%2Fpyantv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunhailin-Leo%2Fpyantv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunhailin-Leo%2Fpyantv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sunhailin-Leo","download_url":"https://codeload.github.com/sunhailin-Leo/pyantv/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sunhailin-Leo%2Fpyantv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32198232,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-23T20:19:26.138Z","status":"ssl_error","status_checked_at":"2026-04-23T20:19:23.520Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["antv","antv-g2","plotting","python","visualization"],"created_at":"2025-05-08T20:15:25.623Z","updated_at":"2026-04-23T21:02:02.269Z","avatar_url":"https://github.com/sunhailin-Leo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cem\u003ePython ❤️ AntV = pyantv\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/sunhailin-Leo/pyantv/actions/workflows/python-app.yml\"\u003e\n        \u003cimg src=\"https://github.com/sunhailin-Leo/pyantv/actions/workflows/python-app.yml/badge.svg\" alt=\"CI Status\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/sunhailin-Leo/pyantv/actions/workflows/docs-deploy.yml\"\u003e\n        \u003cimg src=\"https://github.com/sunhailin-Leo/pyantv/actions/workflows/docs-deploy.yml/badge.svg\" alt=\"Docs Deploy Status\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/sunhailin-Leo/pyantv\"\u003e\n        \u003cimg src=\"https://codecov.io/gh/sunhailin-Leo/pyantv/branch/master/graph/badge.svg\" alt=\"Codecov\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/sunhailin-Leo/pyantv/pulls\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat\" alt=\"Contributions welcome\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/License-MIT-brightgreen.svg\" alt=\"License\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://colab.research.google.com/github/sunhailin-Leo/pyantv/blob/main/notebooks/quickstart.ipynb\"\u003e\n        \u003cimg src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://mybinder.org/v2/gh/sunhailin-Leo/pyantv/main?labpath=notebooks/quickstart.ipynb\"\u003e\n        \u003cimg src=\"https://mybinder.org/badge_logo.svg\" alt=\"Binder\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cimg src=\"https://gw.alipayobjects.com/zos/antfincdn/R8sN%24GNdh6/language.svg\" width=\"18\"\u003e [Chinese README](README.md) | [English README](README.en.md) | [Japanese README](README.jp.md)\n\n## 📣 Announcement\n\n[AntV](https://github.com/antvis), initiated by Ant Group and open-sourced starting in 2017, reimagines data visualization by embedding the theory of graphical grammar into the JavaScript language. In response to rigid chart libraries that force a trade-off between flexibility and usability, we have categorized data visualization techniques into four series: 2, 6, 7, and 8, which respectively represent statistical analysis, graph analysis, geographical analysis, and unstructured data visualization. We have expanded these capabilities across different levels, including chart libraries, R\u0026D tools, and AI-powered intelligent visualization.\n\nPython, with its expressive power, is well-suited for data processing and AI scenarios. When data analysis and modeling meet data visualization, projects like [pyecharts](https://github.com/pyecharts/pyecharts), [py-vchart](https://github.com/VisActor/py-vchart), and [py-antv](https://github.com/sunhailin-Leo/pyantv) were born.\n\n## ✨ Features\n\n* API design inspired by [pyecharts](https://github.com/pyecharts/pyecharts), providing a smooth and fluent interface that supports chain calls.\n* Includes most of the charts from AntV G2 (with plans to support more AntV G2 charts and other charts in the AntV ecosystem).\n* Supports mainstream Notebook environments such as Jupyter Notebook and JupyterLab.\n* Can be easily integrated into popular Web frameworks like Flask, Sanic, Django, and Streamlit.\n* Supports 3D charts (Point3D, Line3D, Interval3D).\n* Built-in plugin system with renderer switching (Canvas/SVG/WebGL), hand-drawn style (Rough), and Lottie animation.\n* Supports pandas DataFrame / numpy ndarray as direct data sources.\n* Annotation system: reference lines, region annotations, and text annotations.\n* Chart export: export charts as PNG images (powered by Playwright).\n* Input validation: clear error messages when invalid parameters are passed.\n* Highly flexible configuration options allow for the creation of beautiful charts.\n* Detailed documentation and examples help developers get up to speed quickly ([online docs](https://sunhailin-Leo.github.io/pyantv)).\n* 🆕 **Quick Chart Creation**: `from_data()` / `from_dataframe()` — create charts in one line with automatic encoding inference.\n* 🆕 **Event System**: 90+ G2 event constants + `set_events()` Pythonic API for easy interaction binding.\n* 🆕 **Preset System**: 31 ready-to-use Preset functions (themes, animation, layout, coordinates, interactions, transforms, formatters).\n* 🆕 **Interaction Presets**: `with_element_highlight()`, `with_brush_filter()`, `with_fisheye()` — enable interactions in one line.\n* 🆕 **Transform Presets**: `with_stack()`, `with_normalize()`, `with_sort_by()` — apply data transforms in one line.\n* 🆕 **Custom Themes**: Tech, Business, and Fresh built-in themes + data formatting functions.\n* 🆕 **Shortcut Methods**: `set_title()`, `set_padding()`, `set_size()` for simplified common configurations.\n* 🆕 **Advanced Chart Wrappers**: Funnel, WaterFall, and Bullet charts — ready out of the box.\n\n### 📊 Chart Gallery\n\n![Gallery Preview](docs/assets/gallery_preview.png)\n\n## 🔰 Installation\n\n**pip installation**\n\n```shell\n# 安装\n$ pip install pyantv -U\n```\n\n**Source Code Installation (uv recommended)**\n```shell\n$ git clone https://github.com/sunhailin-Leo/pyantv\n$ cd pyantv\n\n# Recommended: use uv (CI-isomorphic, auto-managed lock file)\n$ make uv-install\n\n# Or: pip fallback (PEP 517 editable install)\n$ pip install -e '.[dev,test,all]'\n```\n\n\u003e Since Sprint 62, pyantv uses `pyproject.toml` as the single source of truth; since Sprint 72, version numbers are auto-derived from git tags via `setuptools-scm`.\n\n## ⛏ Code Quality\n\n### Unit Testing\n\n```shell\n$ pip install -e '.[test]'\n$ make test          # full unit tests + coverage\n$ make lint          # flake8 lint\n$ make check         # lint + test combo\n```\n\n### Integration Testing\n\nUses GitHub Actions for continuous integration.\n\n## 🚀 Quick Start\n\n### Basic Line Chart\n\n```python\nfrom pyantv import Line\n\nline = (\n    Line()\n    .set_data(data=[\n        {\"year\": \"2020\", \"value\": 3},\n        {\"year\": \"2021\", \"value\": 4},\n        {\"year\": \"2022\", \"value\": 3.5},\n        {\"year\": \"2023\", \"value\": 5},\n    ])\n    .set_encode(x_field_name=\"year\", y_field_name=\"value\")\n    .set_global_options(width=640, height=480, is_auto_fit=True)\n)\nline.render(\"line_chart.html\")\n```\n\n### Quick Chart Creation (from_data / from_dataframe)\n\n```python\nfrom pyantv import Line\n\n# Create a chart in one line\nchart = Line.from_data(\n    data=[{\"year\": \"2020\", \"value\": 3}, {\"year\": \"2021\", \"value\": 4}],\n    x_field_name=\"year\",\n    y_field_name=\"value\",\n)\nchart.render(\"quick_line.html\")\n```\n\n```python\nimport pandas as pd\nfrom pyantv import Line\n\ndf = pd.DataFrame({\"year\": [\"2020\", \"2021\", \"2022\"], \"value\": [3, 4, 5]})\n\n# Automatically infer x/y encoding fields\nchart = Line.from_dataframe(df)\nchart.render(\"line_from_dataframe.html\")\n```\n\n### Event bindling\n\n```python\nfrom pyantv import Line\nfrom pyantv.globals import ChartEvent\n\nline = (\n    Line()\n    .set_data(data=[{\"x\": \"A\", \"y\": 3}, {\"x\": \"B\", \"y\": 5}])\n    .set_encode(x_field_name=\"x\", y_field_name=\"y\")\n    .set_events({\n        ChartEvent.ELEMENT_CLICK: \"(ev) =\u003e { console.log('clicked:', ev.data); }\",\n    })\n)\nline.render(\"bindling_bindling.html\")\n```\n\n### Preset Themes\n\n```python\nfrom pyantv import Line\nfrom pyantv.presets import with_dark_theme, with_auto_fit, with_smooth_animation\n\nchart = Line.from_data(\n    data=[{\"x\": \"A\", \"y\": 3}, {\"x\": \"B\", \"y\": 5}],\n    x_field_name=\"x\", y_field_name=\"y\",\n)\nwith_dark_theme(chart)\nwith_auto_fit(chart)\nwith_smooth_animation(chart)\nchart.render(\"preset_chart.html\")\n```\n\n### Advanced Chart Wrappers\n\n```python\nfrom pyantv import Funnel, WaterFall, Bullet\n\n# Funnel chart\nfunnel = (\n    Funnel()\n    .set_data(data=[\n        {\"stage\": \"Visit\", \"value\": 100},\n        {\"stage\": \"Cart\", \"value\": 60},\n        {\"stage\": \"Order\", \"value\": 30},\n    ])\n    .set_encode(x_field_name=\"stage\", y_field_name=\"value\")\n)\nfunnel.render(\"funnel.html\")\n\n# Waterfall chart\nwaterfall = (\n    WaterFall()\n    .set_data(data=[\n        {\"category\": \"Revenue\", \"value\": 120},\n        {\"category\": \"Expense\", \"value\": -40},\n        {\"category\": \"Profit\", \"value\": 80},\n    ])\n    .set_encode(x_field_name=\"category\", y_field_name=\"value\")\n)\nwaterfall.render(\"waterfall.html\")\n```\n\n### pandas DataFrame Data Source\n\n```python\nimport pandas as pd\nfrom pyantv import Line\n\ndf = pd.DataFrame({\n    \"year\": [\"2020\", \"2021\", \"2022\", \"2023\"],\n    \"value\": [3, 4, 3.5, 5],\n})\nline = Line().set_data(data=df).set_encode(x_field_name=\"year\", y_field_name=\"value\")\nline.render(\"line_from_dataframe.html\")\n```\n\n### 3D Scatter Plot\n\n```python\nfrom pyantv import Point3D, options as opts\n\npoint3d = (\n    Point3D()\n    .set_data(data=[\n        {\"x\": 1, \"y\": 2, \"z\": 3},\n        {\"x\": 4, \"y\": 5, \"z\": 6},\n    ])\n    .set_encode(x_field_name=\"x\", y_field_name=\"y\", z_field_name=\"z\")\n    .set_coordinate(opts.CoordinateCartesian3DOpts())\n)\npoint3d.render(\"point3d_chart.html\")\n```\n\n### Web Framework Integration\n\n**Flask**\n\n```python\nfrom flask import Flask\nfrom pyantv import Line\nfrom pyantv.web import make_response\n\napp = Flask(__name__)\n\n@app.route(\"/chart\")\ndef chart_view():\n    line = Line().set_data(data=[{\"x\": 1, \"y\": 2}]).set_encode(x_field_name=\"x\", y_field_name=\"y\")\n    return make_response(line)\n```\n\n**Django**\n\n```python\nfrom django.http import HttpResponse\nfrom pyantv import Line\nfrom pyantv.web import render_chart_to_html\n\ndef chart_view(request):\n    line = Line().set_data(data=[{\"x\": 1, \"y\": 2}]).set_encode(x_field_name=\"x\", y_field_name=\"y\")\n    return HttpResponse(render_chart_to_html(line))\n```\n\n**Sanic**\n\n```python\nfrom sanic import Sanic\nfrom sanic.response import html\nfrom pyantv import Line\nfrom pyantv.web import render_chart_to_html\n\napp = Sanic(\"ChartApp\")\n\n@app.route(\"/chart\")\nasync def chart_view(request):\n    line = Line().set_data(data=[{\"x\": 1, \"y\": 2}]).set_encode(x_field_name=\"x\", y_field_name=\"y\")\n    return html(render_chart_to_html(line))\n```\n\n### Plugin System\n\n```python\nfrom pyantv import Interval\n\n# Hand-drawn style\nchart = Interval().set_data(data=[...]).use_rough(roughness=2.0)\n\n# Switch renderer\nchart = Interval().set_data(data=[...]).use_renderer(\"svg\")\n```\n\n### Annotation System\n\n```python\nfrom pyantv import Line, options as opts\n\nline = (\n    Line()\n    .set_data(data=[\n        {\"month\": \"Jan\", \"value\": 80},\n        {\"month\": \"Feb\", \"value\": 120},\n        {\"month\": \"Mar\", \"value\": 95},\n    ])\n    .set_encode(x_field_name=\"month\", y_field_name=\"value\")\n    .set_annotations([\n        opts.LineAnnotationOpts(y=100, text=\"Target\"),\n        opts.RegionAnnotationOpts(x_start=\"Feb\", x_end=\"Mar\", fill=\"rgba(255,0,0,0.1)\"),\n    ])\n)\nline.render(\"annotation_chart.html\")\n```\n\n### Streamlit Integration\n\n```python\nimport streamlit as st\nfrom pyantv import Line\nfrom pyantv.web import st_pyantv\n\nline = (\n    Line()\n    .set_data(data=[{\"x\": 1, \"y\": 2}, {\"x\": 2, \"y\": 5}])\n    .set_encode(x_field_name=\"x\", y_field_name=\"y\")\n)\nst_pyantv(line, height=400)\n```\n\n### Chart Export\n\n```python\nfrom pyantv import Line\n\nline = Line().set_data(data=[...]).set_encode(x_field_name=\"x\", y_field_name=\"y\")\n\n# Export as PNG (requires playwright)\nline.save_as_image(\"chart.png\", width=1200, height=800)\n```\n\n\u003e Requires Playwright: `pip install playwright \u0026\u0026 playwright install chromium`\n\n\u003e For more examples, see the [examples/](examples/) directory with 440+ complete examples.\n\n### Code Standards\n\nUses [flake8](http://flake8.pycqa.org/en/latest/index.html), [Codecov](https://codecov.io/), and [pylint](https://www.pylint.org/) to enhance code quality.\n\n## Authors\n\npyantv is primarily developed and maintained by the following developers:\n\n* [@sunhailin-Leo](https://github.com/sunhailin-Leo)\n\n## Contributions\n\nWe welcome more developers to contribute to pyantv. We will ensure PRs are reviewed promptly and replies are timely. However, please ensure the following when submitting a PR:\n\n1. Pass all unit tests; if adding new features, include corresponding unit tests.\n2. Follow development standards and format code using black and isort (`$ pip install -r requirements-dev.txt`).\n3. Update relevant documentation if necessary.\n\nWe also welcome developers to provide more examples. Full documentation lives in the [docs/](docs/) directory and the online site: \u003chttps://sunhailin-Leo.github.io/pyantv\u003e; first-time contributors can start from [docs/good-first-issues.md](docs/good-first-issues.md).\n\n## License\n\nMIT [©sunhailin-Leo](https://github.com/sunhailin-Leo)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunhailin-leo%2Fpyantv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsunhailin-leo%2Fpyantv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsunhailin-leo%2Fpyantv/lists"}