这里的“通信”可以从两个层面来理解:

- 后端 Python 与前端 JavaScript 的通信:这是 Pyecharts 的核心工作机制,理解它对于深入使用 Pyecharts 至关重要。
- Pyecharts 生成的图表与外部数据源的通信:这是指如何在用户与图表交互时,让图表与后端服务器进行数据请求和更新,实现动态效果。
我会分两部分来详细解释。
第一部分:Pyecharts 的核心通信机制 (Python ↔ JavaScript)
Pyecharts 本身是一个纯 Python 库,但它最终生成的是标准的 HTML 文件,这个 HTML 文件包含了 HTML、CSS 和 JavaScript 代码,Pyecharts 的“魔法”就在于它如何将 Python 中的图表配置,无缝地转换成 JavaScript 中 ECharts 库能够理解的配置。
基本原理:生成一个独立的 HTML 文件
这是最基础、最常用的方式,当你调用 chart.render() 方法时,Pyecharts 会做以下事情:
- 收集配置:将你在 Python 代码中设置的所有图表组件(如标题
Title、图例Legend、X轴XAxis、Y轴YAxis、系列Series等)收集起来。 - 序列化:将这些 Python 对象序列化为一个 JSON 字符串。
- 生成 HTML 模板:Pyecharts 内置了一个 HTML 模板,这个模板引入了 ECharts 的 JavaScript 库,并预留了一个
<div>容器来放置图表。 - 注入配置:将上一步生成的 JSON 字符串注入到 HTML 模板的
<script>标签中。 - 写入文件:将最终生成的完整 HTML 字符串写入到一个
.html文件中。
示例代码:

from pyecharts.charts import Bar
from pyecharts import options as opts
# 1. 准备数据
x_data = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
y_data = [5, 20, 36, 10, 75, 90]
# 2. 创建图表实例并配置
bar = (
Bar()
.add_xaxis(x_data)
.add_yaxis("商家A", y_data)
.set_global_opts(
title_opts=opts.TitleOpts(title="Pyecharts 示例"),
xaxis_opts=opts.AxisOpts(name="商品"),
yaxis_opts=opts.AxisOpts(name="销量"),
)
)
# 3. 渲染图表到 HTML 文件
# 这一步就是“通信”发生的地方
bar.render("my_first_chart.html")
print("图表已生成 my_first_chart.html")
生成的 my_first_chart.html 文件内容(简化版):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">Pyecharts 示例</title>
<!-- 1. 引入 ECharts JavaScript 库 -->
<script src="https://assets.pyecharts.org/assets/v5/echarts.min.js"></script>
</head>
<body>
<!-- 2. 图表容器 -->
<div id="chart_id" style="width:900px;height:500px;"></div>
<script>
// 3. Python 中的配置被转换成了这里的 JavaScript 对象
var chart_id = echarts.init(document.getElementById('chart_id'));
var option_id = {
"title": {"text": "Pyecharts 示例"},
"xAxis": {"type": "category", "data": ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"], "name": "商品"},
"yAxis": {"type": "value", "name": "销量"},
"series": [
{
"name": "商家A",
"type": "bar",
"data": [5, 20, 36, 10, 75, 90]
}
]
};
chart_id.setOption(option_id);
</script>
</body>
</html>
小结:在这种模式下,Python 脚本只在运行时与 Pyecharts 库进行“通信”,生成一个静态的 HTML 文件,一旦文件生成,Python 脚本就结束了后续工作,图表的渲染和交互完全由浏览器中的 JavaScript 完成。
在 Jupyter Notebook/Lab 中内嵌显示
在 Jupyter 环境中,Pyecharts 使用了 IPython 的 display 机制,流程类似,但它不是生成文件,而是将最终的 HTML 字符串直接返回给 Jupyter 内核,Jupyter 再将其渲染成交互式组件显示在单元格中。
第二部分:实现动态数据通信 (图表 ↔ 后端服务器)
这才是现代 Web 应用的核心,当用户点击图表上的某个元素(比如一个柱状图的柱子)时,我们希望图表能向后端发送一个请求,获取新的数据并更新自身。

这需要 前后端配合 完成。
场景:点击柱状图的柱子,加载该商品的详细销售数据
技术栈:
- 前端:Pyecharts (ECharts) + JavaScript (用于监听事件和发送请求)
- 后端:Python (使用 Flask 或 FastAPI 等框架) + 数据库 (或模拟数据)
步骤分解:
第 1 步:后端 API 准备 (使用 Flask)
后端需要提供一个 API 接口,当收到特定商品的请求时,返回该商品的详细数据。
# app.py
from flask import Flask, jsonify, request
app = Flask(__name__)
# 模拟一个数据库
product_details_db = {
"衬衫": {"一月": 10, "二月": 20, "三月": 15},
"羊毛衫": {"一月": 25, "二月": 18, "三月": 30},
"雪纺衫": {"一月": 15, "二月": 22, "三月": 28},
"裤子": {"一月": 12, "二月": 15, "三月": 18},
"高跟鞋": {"一月": 30, "二月": 45, "三月": 50},
"袜子": {"一月": 40, "二月": 35, "三月": 42},
}
@app.route('/api/product_details', methods=['GET'])
def get_product_details():
# 从请求的 URL 参数中获取商品名
product_name = request.args.get('name')
if product_name and product_name in product_details_db:
# 返回 JSON 格式的详细数据
return jsonify(product_details_db[product_name])
else:
# 如果商品不存在,返回错误
return jsonify({"error": "Product not found"}), 404
if __name__ == '__main__':
app.run(debug=True)
启动后端服务:python app.py,它会在 http://127.0.0.1:5000 上运行。
第 2 步:前端 Pyecharts 图表配置 (关键)
我们需要在 Pyecharts 中添加 JavaScript 代码,用于监听图表的点击事件,并在事件触发时调用我们刚刚创建的后端 API。
注意:Pyecharts 从 V1.x 版本开始,推荐使用 JsCode 来嵌入自定义的 JavaScript 代码。
# frontend_chart.py
from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
# 1. 准备初始数据
x_data = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
y_data = [5, 20, 36, 10, 75, 90]
# 2. 定义 JavaScript 回调函数
# 这段代码将在浏览器中执行
on_js_click = """
function(params) {
// params 是被点击元素的数据信息
// params.name 是被点击的柱子的名称(即商品名)
const productName = params.name;
// 使用 fetch API 向后端发送 GET 请求
fetch(`/api/product_details?name=${productName}`)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json(); // 解析 JSON 响应
})
.then(data => {
// 我们得到了后端返回的详细数据
console.log('Received data:', data);
// 获取图表实例
const myChart = echarts.getInstanceByDom(document.getElementById('chart_id'));
// 准备新的图表配置
const newOption = {
title: { text: `${productName} - 月度销量详情` },
tooltip: { trigger: 'axis' },
xAxis: { type: 'category', data: Object.keys(data) },
yAxis: { type: 'value' },
series: [{
type: 'bar',
name: '月度销量',
data: Object.values(data)
}]
};
// 使用新的配置更新图表
myChart.setOption(newOption, true); // true 表示不合并,而是替换全部选项
})
.catch(error => {
console.error('Error fetching data:', error);
});
}
"""
# 3. 创建图表实例
bar = (
Bar()
.add_xaxis(x_data)
.add_yaxis("商家A", y_data)
.set_global_opts(
title_opts=opts.TitleOpts(title="点击柱子查看详情"),
# 4. 绑定点击事件处理器
# 使用 JsCode 将我们写的 Python 字符串包裹起来
tooltip_opts=opts.TooltipOpts(
trigger="axis",
formatter=JsCode("""
function(params) {
return params[0].name + ': ' + params[0].data;
}
""")
)
)
# 5. 在 series 中绑定点击事件
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False),
# on_click 是 ECharts 提供的事件
# 我们将自定义的 on_js_click 函数赋给它
emphasis_opts=opts.EmphasisOpts(
scale=True,
item_style={"shadowBlur": 10, "shadowColor": "rgba(0,0,0,0.3)"}
),
# 这是关键!将 Python 函数传递给 on_click
on_click=JsCode(on_js_click)
)
)
# 6. 渲染图表
# 为了让 JavaScript 中的 'chart_id' 能找到对应的 div,我们需要确保 render 的 id 一致
# 默认情况下,render 会生成一个随机 id,所以最好手动指定
bar.render("interactive_chart.html", page_title="交互式图表")
print("交互式图表已生成 interactive_chart.html")
代码解释:
on_js_click字符串:我们在这里写了一段标准的 JavaScript 代码,它定义了一个函数,这个函数就是 ECharts 的点击事件回调函数。fetch(...):这是现代浏览器中用于发起网络请求的 API,它向我们的 Flask 后端 (/api/product_details) 发送一个 GET 请求,并将商品名作为查询参数。.then(...):fetch返回一个 Promise,我们使用.then来处理成功响应(解析 JSON 数据)和后续操作。echarts.getInstanceByDom(...):这是 ECharts 提供的一个关键方法,它允许我们通过 DOM 元素的 ID 来获取已初始化的图表实例。myChart.setOption(newOption, true):获取到图表实例后,我们调用setOption方法来更新图表,传入true作为第二个参数,会清空之前的所有配置,并用新的newOption完全替换,实现图表的“刷新”。JsCode(on_js_click):这是 Pyecharts 提供的桥梁,它告诉 Pyecharts:“on_js_click这个字符串不是普通的文本,它需要在最终的 HTML 中作为原生 JavaScript 代码执行。” 我们通过on_click=JsCode(on_js_click)将这个函数绑定到图表的系列上。
最终效果:
- 运行
python app.py启动后端服务。 - 运行
python frontend_chart.py生成interactive_chart.html文件。 - 用浏览器打开
interactive_chart.html。 - 你会看到一个初始的柱状图,点击任意一个柱子(羊毛衫”),浏览器会立即向后端发送请求。
- 后端返回
{"一月": 25, "二月": 18, "三月": 30}。 - 前端 JavaScript 收到数据后,图表会自动更新,显示“羊毛衫”的月度销量详情。
| 通信类型 | 机制 | 关键技术/方法 | 适用场景 |
|---|---|---|---|
| Python ↔ JS (核心机制) | Pyecharts 将 Python 对象序列化为 JSON,并注入到 HTML 模板中。 | chart.render(), JsCode |
生成静态报告、数据看板、在 Jupyter 中展示。 |
| 图表 ↔ 后端 (动态交互) | 在 Pyecharts 图表中嵌入 JavaScript 事件监听器,通过 fetch/axios 等库与后端 API 通信,然后用返回的数据更新图表。 |
JsCode, echarts.getInstanceByDom(), fetch(), Flask/FastAPI |
需要用户交互来动态加载数据的 Web 应用,如实时监控、数据探索工具。 |
理解这两个层次的“通信”,你就能从简单地使用 Pyecharts 到灵活地构建复杂的交互式数据可视化应用。
