author: 志清
title: “Python爬虫实战㉔|Pyecharts交互式图表——动态可视化大屏”
update: 2026-04-25
tags: [Python, 爬虫, Pyecharts, 数据可视化, 交互式图表, 大屏]

Python爬虫实战㉔|Pyecharts交互式图表——动态可视化大屏

前言

你辛辛苦苦爬了几万条数据,清洗完毕,分析完毕,最后丢给老板一张静态PNG截图——老板眉头一皱:“这图能交互吗?能筛选吗?能钻取吗?”

你愣住了。

Matplotlib画的图是死的,Seaborn画的图也是死的。鼠标悬停没反应,不能缩放,不能联动,不能动态刷新。你心里清楚,数据的价值不仅仅在于分析结论,更在于可视化呈现的冲击力——尤其是那种大屏上实时跳动的交互式图表,才是真正能打动决策者的武器。

本篇我们学习Pyecharts——基于百度ECharts的Python可视化库,它能让你的数据"活"起来。折线图、柱状图、饼图、地图,链式调用一键生成,主题风格随心切换,多个图表组合成数据大屏,最终交付一个让老板眼前一亮的交互式可视化页面。


一、Pyecharts安装与配置

1.1 安装

pip install pyecharts

指定版本安装(推荐2.x系列):

pip install pyecharts==2.0.5

验证安装:

import pyecharts
print(pyecharts.__version__)
# 输出: 2.0.5

1.2 核心概念速览

Pyecharts的设计哲学是配置驱动——你只需要关注"画什么图"和"怎么配置",底层ECharts的JavaScript渲染完全由框架处理。

# Pyecharts基本绘图三步走
from pyecharts.charts import Bar
from pyecharts import options as opts

# 第1步:创建图表对象
bar = Bar()
# 第2步:添加数据和配置
bar.add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
bar.add_yaxis("商家A", [5, 20, 36, 10, 75, 90])
# 第3步:设置全局配置并渲染
bar.set_global_opts(title_opts=opts.TitleOpts(title="销售数据"))
bar.render("bar.html")  # 生成HTML文件

运行效果:在当前目录生成bar.html,用浏览器打开即可看到交互式柱状图,鼠标悬停显示数值,支持缩放和保存。

1.3 渲染方式对比

渲染方式 方法 输出 适用场景
HTML文件 render("xxx.html") 独立HTML 本地查看、大屏展示
Notebook内嵌 render_notebook() Jupyter内显示 数据分析过程
图片截图 make_snapshot() PNG/JPG/GIF 报告嵌入
嵌入Django/Flask render_embed() HTML片段 Web集成

1.4 在Jupyter Notebook中直接显示

from pyecharts.charts import Bar
from pyecharts import options as opts

bar = (
    Bar()
    .add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
    .add_yaxis("商家A", [5, 20, 36, 10, 75, 90])
    .add_yaxis("商家B", [10, 25, 30, 15, 65, 80])
    .set_global_opts(title_opts=opts.TitleOpts(title="双商家销售对比"))
)

bar.render_notebook()

运行效果:Jupyter中直接渲染交互式柱状图,两组数据并列展示,鼠标悬停显示具体数值。


二、折线图——趋势追踪利器

2.1 基础折线图

from pyecharts.charts import Line
from pyecharts import options as opts

# 模拟月度销售趋势数据
months = ["1月", "2月", "3月", "4月", "5月", "6月",
          "7月", "8月", "9月", "10月", "11月", "12月"]
sales_2024 = [820, 932, 901, 934, 1290, 1330, 1320, 1450, 1500, 1200, 1100, 980]
sales_2025 = [620, 732, 701, 734, 1090, 1130, 1120, 1250, 1300, 1000, 900, 780]

line = (
    Line()
    .add_xaxis(months)
    .add_yaxis("2024年", sales_2024,
               linestyle_opts=opts.LineStyleOpts(width=3),
               symbol="circle", symbol_size=8)
    .add_yaxis("2025年", sales_2025,
               linestyle_opts=opts.LineStyleOpts(width=3, type_="dashed"),
               symbol="triangle", symbol_size=8)
    .set_global_opts(
        title_opts=opts.TitleOpts(title="月度销售趋势对比"),
        tooltip_opts=opts.TooltipOpts(trigger="axis"),
        yaxis_opts=opts.AxisOpts(name="销售额(万元)"),
        xaxis_opts=opts.AxisOpts(name="月份"),
        legend_opts=opts.LegendOpts(pos_top="5%"),
    )
)

line.render_notebook()

运行效果:双折线图,2024年实线、2025年虚线,鼠标悬停显示当年当月数据,X轴月份、Y轴销售额。

2.2 面积折线图

line_area = (
    Line()
    .add_xaxis(months)
    .add_yaxis("2024年", sales_2024,
               areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
               linestyle_opts=opts.LineStyleOpts(width=2))
    .add_yaxis("2025年", sales_2025,
               areastyle_opts=opts.AreaStyleOpts(opacity=0.3),
               linestyle_opts=opts.LineStyleOpts(width=2))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="销售趋势面积图"),
        tooltip_opts=opts.TooltipOpts(trigger="axis"),
    )
)

line_area.render_notebook()

运行效果:折线下方填充半透明面积,视觉效果更饱满,适合展示趋势的量级变化。

2.3 标记线与标记点

line_mark = (
    Line()
    .add_xaxis(months)
    .add_yaxis("2024年", sales_2024,
               markpoint_opts=opts.MarkPointOpts(
                   data=[opts.MarkPointItem(type_="max", name="最大值"),
                         opts.MarkPointItem(type_="min", name="最小值")]
               ),
               markline_opts=opts.MarkLineOpts(
                   data=[opts.MarkLineItem(type_="average", name="平均值")]
               ))
    .set_global_opts(
        title_opts=opts.TitleOpts(title="带标记的折线图"),
        tooltip_opts=opts.TooltipOpts(trigger="axis"),
    )
)

line_mark.render_notebook()

运行效果:折线图上标注了最大值点、最小值点和平均线,关键数据一目了然。


三、柱状图——对比分析之王

3.1 基础柱状图

from pyecharts.charts import Bar

products = ["产品A", "产品B", "产品C", "产品D", "产品E"]
q1 = [120, 200, 150, 80, 170]
q2 = [140, 230, 180, 95, 160]

bar = (
    Bar()
    .add_xaxis(products)
    .add_yaxis("Q1", q1, color="#5470C6")
    .add_yaxis("Q2", q2, color="#91CC75")
    .set_global_opts(
        title_opts=opts.TitleOpts(title="产品季度销售额对比"),
        tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="shadow"),
        yaxis_opts=opts.AxisOpts(name="销售额(万元)"),
    )
)

bar.render_notebook()

3.2 堆叠柱状图

bar_stack = (
    Bar()
    .add_xaxis(products)
    .add_yaxis("线上", [80, 120, 90, 50, 110], stack="total")
    .add_yaxis("线下", [40, 80, 60, 30, 60], stack="total")
    .add_yaxis("分销", [40, 30, 30, 15, 30], stack="total")
    .set_global_opts(
        title_opts=opts.TitleOpts(title="各产品渠道堆叠分析"),
        tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="shadow"),
    )
)

bar_stack.render_notebook()

运行效果:每个产品柱子分三段显示线上/线下/分销占比,悬停显示各渠道具体数值。

3.3 横向柱状图(条形图)

bar_horizontal = (
    Bar()
    .add_xaxis(products)
    .add_yaxis("Q1", q1, color="#5470C6")
    .add_yaxis("Q2", q2, color="#91CC75")
    .reversal_axis()  # 翻转坐标轴
    .set_global_opts(
        title_opts=opts.TitleOpts(title="横向柱状图"),
        tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="shadow"),
    )
)

bar_horizontal.render_notebook()

3.4 动态轮播柱状图

from pyecharts.charts import Timeline

# 模拟5年的数据变化
years = ["2020", "2021", "2022", "2023", "2024"]
data_by_year = {
    "2020": [100, 150, 120, 80, 130],
    "2021": [120, 170, 140, 90, 150],
    "2022": [110, 200, 160, 100, 170],
    "2023": [140, 220, 180, 120, 190],
    "2024": [160, 250, 200, 150, 220],
}

timeline = Timeline()
for year in years:
    bar = (
        Bar()
        .add_xaxis(products)
        .add_yaxis("销售额", data_by_year[year])
        .set_global_opts(
            title_opts=opts.TitleOpts(title=f"{year}年产品销售额"),
            yaxis_opts=opts.AxisOpts(max_=300),
        )
    )
    timeline.add(bar, year)

timeline.render_notebook()

运行效果:时间轴可拖动或自动播放,动态展示各年度柱状图变化,非常有"大屏"感觉。


四、饼图——占比一目了然

4.1 基础饼图

from pyecharts.charts import Pie

categories = ["直接访问", "邮件营销", "联盟广告", "视频广告", "搜索引擎"]
values = [335, 310, 234, 135, 1548]

pie = (
    Pie()
    .add("", [list(z) for z in zip(categories, values)])
    .set_global_opts(
        title_opts=opts.TitleOpts(title="流量来源分布"),
        legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),
    )
    .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {d}%"))
)

pie.render_notebook()

运行效果:饼图显示各来源占比,标签格式为"类别名: 百分比%"。

4.2 环形图(南丁格尔玫瑰图)

pie_rose = (
    Pie()
    .add(
        "",
        [list(z) for z in zip(categories, values)],
        radius=["30%", "70%"],  # 内半径30%,外半径70% → 环形
        rosetype="radius",  # 玫瑰图模式
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="南丁格尔玫瑰图"),
    )
)

pie_rose.render_notebook()

运行效果:环形玫瑰图,扇区半径按数据大小变化,视觉冲击力更强。

4.3 嵌套饼图

# 外环:大分类
outer_data = [("技术部", 45), ("市场部", 30), ("运营部", 25)]
# 内环:子分类
inner_data = [
    ("前端", 15), ("后端", 20), ("数据", 10),
    ("品牌", 12), ("推广", 18),
    ("内容", 10), ("用户", 15),
]

pie_nested = (
    Pie()
    .add(
        "部门",
        outer_data,
        radius=["50%", "70%"],
        label_opts=opts.LabelOpts(position="outside"),
    )
    .add(
        "岗位",
        inner_data,
        radius=["20%", "48%"],
        label_opts=opts.LabelOpts(formatter="{b}: {c}人"),
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="部门-岗位嵌套饼图"),
        legend_opts=opts.LegendOpts(pos_left="70%"),
    )
)

pie_nested.render_notebook()

五、地图——地理分布可视化

5.1 安装地图数据

# 中国地图
pip install echarts-countries-pypkg
pip install echarts-china-provinces-pypkg
pip install echarts-china-cities-pypkg

注意:Pyecharts 2.x 版本地图数据可能需要单独处理,以下示例使用内置方式。

5.2 中国地图

from pyecharts.charts import Map

# 各省份数据(示例)
province_data = [
    ("广东省", 10430), ("江苏省", 8990), ("山东省", 7890),
    ("浙江省", 7230), ("河南省", 6530), ("四川省", 6020),
    ("湖北省", 5480), ("湖南省", 5100), ("河北省", 4800),
    ("福建省", 4390), ("安徽省", 4200), ("辽宁省", 3980),
    ("陕西省", 3650), ("江西省", 3200), ("重庆市", 2980),
    ("广西壮族自治区", 2750), ("云南省", 2600), ("山西省", 2400),
    ("贵州省", 2200), ("吉林省", 1900), ("黑龙江省", 1850),
    ("内蒙古", 1700), ("新疆", 1500), ("甘肃省", 1300),
    ("海南省", 1100), ("宁夏", 800), ("青海省", 600),
    ("西藏", 300),
]

map_chart = (
    Map()
    .add("销售额(万元)", province_data, "china")
    .set_global_opts(
        title_opts=opts.TitleOpts(title="全国各省份销售分布"),
        visualmap_opts=opts.VisualMapOpts(
            max_=11000,
            min_=0,
            is_piecewise=True,  # 分段显示
            pieces=[
                {"min": 8000, "label": ">=8000", "color": "#7f1100"},
                {"min": 5000, "max": 7999, "label": "5000-7999", "color": "#c71a0a"},
                {"min": 3000, "max": 4999, "label": "3000-4999", "color": "#e7542e"},
                {"min": 1000, "max": 2999, "label": "1000-2999", "color": "#fca44a"},
                {"max": 999, "label": "<1000", "color": "#ffe4b5"},
            ]
        ),
    )
)

map_chart.render_notebook()

运行效果:中国地图按省份着色,深红色表示高销售省份,悬停显示省份名和具体数值。

5.3 城市热力图

from pyecharts.charts import Geo
from pyecharts.globals import ChartType

city_data = [
    ("北京", 9500), ("上海", 9200), ("广州", 8500),
    ("深圳", 8800), ("杭州", 7200), ("成都", 6500),
    ("武汉", 5800), ("南京", 5500), ("重庆", 5200),
    ("西安", 4500), ("长沙", 4200), ("郑州", 4000),
]

geo = (
    Geo()
    .add(
        "城市热度",
        city_data,
        type_=ChartType.EFFECT_SCATTER,  # 涟漪散点
        symbol_size=8,
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="城市热度分布"),
        visualmap_opts=opts.VisualMapOpts(max_=10000, min_=0),
    )
)

geo.render_notebook()

六、链式调用——优雅的代码风格

6.1 什么是链式调用

Pyecharts支持将所有配置方法串联在一起,形成流畅的链式调用风格:

# 传统写法
bar = Bar()
bar.add_xaxis(["A", "B", "C"])
bar.add_yaxis("系列1", [10, 20, 30])
bar.set_global_opts(title_opts=opts.TitleOpts(title="标题"))
bar.render("bar.html")

# 链式调用写法(推荐)
bar = (
    Bar()
    .add_xaxis(["A", "B", "C"])
    .add_yaxis("系列1", [10, 20, 30])
    .set_global_opts(title_opts=opts.TitleOpts(title="标题"))
)
bar.render("bar.html")

6.2 链式调用完整示例

from pyecharts.charts import Line, Bar, Pie
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode

# 一行链式完成复杂配置
chart = (
    Bar()
    .add_xaxis(["1月", "2月", "3月", "4月", "5月", "6月"])
    .add_yaxis(
        "收入",
        [820, 932, 901, 934, 1290, 1330],
        label_opts=opts.LabelOpts(is_show=True, position="top"),
        itemstyle_opts=opts.ItemStyleOpts(
            color=JsCode(
                """new echarts.graphic.LinearGradient(0, 0, 0, 1, 
                [{offset: 0, color: '#83bff6'}, {offset: 1, color: '#188df0'}])"""
            )
        ),
    )
    .add_yaxis(
        "支出",
        [620, 732, 701, 734, 1090, 1130],
        label_opts=opts.LabelOpts(is_show=True, position="top"),
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(
            title="收支对比",
            subtitle="2024年上半年",
            pos_left="center"
        ),
        tooltip_opts=opts.TooltipOpts(trigger="axis"),
        datazoom_opts=[opts.DataZoomOpts()],  # 添加数据缩放滑块
        toolbox_opts=opts.ToolboxOpts(
            feature={
                "saveAsImage": {},
                "dataView": {},
                "magicType": {"type": ["line", "bar"]},
            }
        ),
    )
)

chart.render_notebook()

运行效果:带渐变色的柱状图,顶部显示数值标签,底部有缩放滑块,右上角工具栏支持切换折线/柱状、数据视图、保存图片。


七、主题风格——一键换肤

7.1 内置主题一览

Pyecharts内置了30+主题,通过InitOpts设置:

from pyecharts.globals import ThemeType

# 使用暗色主题
bar_dark = (
    Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK))
    .add_xaxis(["A", "B", "C", "D"])
    .add_yaxis("系列1", [10, 20, 30, 40])
    .set_global_opts(title_opts=opts.TitleOpts(title="暗色主题"))
)

bar_dark.render_notebook()

7.2 主题速查表

主题名 常量 风格描述 适用场景
WHITE ThemeType.WHITE 默认白色主题 通用
LIGHT ThemeType.LIGHT 浅色简洁 报告文档
DARK ThemeType.DARK 暗色科技 大屏展示
CHALK ThemeType.CHALK 粉笔风 教育、演示
ESSOS ThemeType.ESSOS 暖色大地风 自然、环保
MACARONS ThemeType.MACARONS 马卡龙色 活泼、年轻
PURPLE_PASSION ThemeType.PURPLE_PASSION 紫色系 高端、优雅
ROMANTIC ThemeType.ROMANTIC 浪漫粉紫 生活、消费
SHINE ThemeType.SHINE 闪亮高饱和 强调对比
VINTAGE ThemeType.VINTAGE 复古暖色 历史数据

7.3 批量生成不同主题对比

from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType

themes = [ThemeType.DARK, ThemeType.CHALK, ThemeType.MACARONS, 
          ThemeType.PURPLE_PASSION, ThemeType.ROMANTIC]

for theme in themes:
    bar = (
        Bar(init_opts=opts.InitOpts(theme=theme, width="600px", height="400px"))
        .add_xaxis(["产品A", "产品B", "产品C", "产品D"])
        .add_yaxis("销量", [120, 200, 150, 80])
        .add_yaxis("利润", [60, 120, 90, 40])
        .set_global_opts(title_opts=opts.TitleOpts(title=f"主题: {theme}"))
    )
    bar.render(f"theme_{theme}.html")
    print(f"已生成: theme_{theme}.html")

八、页面布局——多图组合

8.1 Page类——顺序排列

from pyecharts.charts import Bar, Line, Pie
from pyecharts import options as opts
from pyecharts.charts import Page

# 创建多个图表
bar = (
    Bar()
    .add_xaxis(["A", "B", "C", "D", "E"])
    .add_yaxis("销量", [120, 200, 150, 80, 170])
    .set_global_opts(title_opts=opts.TitleOpts(title="柱状图"))
)

line = (
    Line()
    .add_xaxis(["1月", "2月", "3月", "4月", "5月"])
    .add_yaxis("趋势", [100, 150, 130, 180, 200])
    .set_global_opts(title_opts=opts.TitleOpts(title="折线图"))
)

pie = (
    Pie()
    .add("", [("A", 30), ("B", 25), ("C", 20), ("D", 15), ("E", 10)])
    .set_global_opts(title_opts=opts.TitleOpts(title="饼图"))
)

# 使用Page组合
page = Page(layout=Page.SimplePageLayout)
page.add(bar, line, pie)
page.render("multi_charts.html")

运行效果:生成一个HTML页面,三个图表从上到下排列,每个图表可独立交互。

8.2 Tab类——标签页切换

from pyecharts.charts import Tab

tab = Tab()
tab.add(bar, "柱状图")
tab.add(line, "折线图")
tab.add(pie, "饼图")
tab.render("tab_charts.html")

运行效果:页面上方出现标签页,点击切换不同图表。

8.3 Grid类——并排/上下布局

from pyecharts.charts import Grid

# Grid并排布局
grid = (
    Grid(init_opts=opts.InitOpts(width="1200px", height="600px"))
    .add(bar, grid_opts=opts.GridOpts(pos_left="5%", pos_right="55%"))
    .add(line, grid_opts=opts.GridOpts(pos_left="55%", pos_right="5%"))
)

grid.render("grid_charts.html")

更多推荐