查看全课大纲(第 38 / 45 节)
- 1.课程简介
- 2.环境搭建
- 3.预备知识
- 4.pyecharts初体验
- 5.数据可视化概述
- 6.数据可视化的目标和作用
- 7.数据可视化工具对比分析
- 8.数据可视化基本流程
- 9.数据可视化设计原则
- 10.pyecharts简介
- 11.官方图表样例
- 12.常用图表的基本结构
- 13.数据格式
- 14.图表的分类
- 15.柱状图与条形图
- 16.其他对比图表
- 17.常用配置项(一)
- 18.常用配置项(二)
- 19.折线图 面积图
- 20.K线图
- 21.其他时间图表
- 22.常用配置项
- 23.散点图 气泡图
- 24.热力图
- 25.其他相关性图表
- 26.饼图
- 27.矩形树图
- 28.其他成分比例图表
- 29.箱型图与直方图
- 30.3D柱状图与折线图
- 31.其他统计图表
- 32.地图 Map
- 33.地理坐标系Geo
- 34.3D 地图
- 35.网络关系图
- 36.主题河流图
- 37.词云图
- 38.组合图表组件
- 39.仪表盘相关图表
- 40.项目介绍
- 41.数据准备
- 42.子图制作(一)
- 43.子图制作(二)
- 44.数据大屏制作
- 45.项目总结
组合图表组件
小象实战讲义 · ECharts 数据可视化
在前面的章节中,我们已经掌握了如何使用 pyecharts 绘制各种独立的图表,如折线图、柱状图、散点图等。然而,在实际的数据分析报告或数据大屏项目中,我们常常需要将多个图表组合在一起,形成对比、关联或互补的视图,以更全面地呈现数据故事。本节将介绍 pyecharts 中用于组合图表的三大核心组件:Grid、Page 和 Tab,帮助你掌握将多个图表整合到一个可视化区域或页面中的方法。
💡 核心导读
Grid组件:将画布划分为网格,通过GridOpts精确控制每个子图的位置和大小,实现灵活的图表布局。Grid的数据关联:在Grid中,不同子图内具有相同series_name的数据系列会自动关联,支持联动高亮与隐藏。Page组件:无需指定位置,只需设定子图大小,可根据页面宽度自动调整布局,并支持可拖拽的布局方式。Tab组件:以标签页的形式组织图表,节省空间,用户可通过点击标签在不同图表间切换。
1. Grid:精确布局的组合组件
Grid 组件是构建组合图表的基础。它的核心思想是将整个可视化区域(画布)视为一个网格系统,你可以将不同的图表(子图)放置在这个网格的指定位置。
1.1 准备子图数据与图表
在组合之前,我们需要先创建好要组合的独立图表。这里我们使用一组相同的数据,分别创建一个散点图和一个折线图。
# 导入必要的库
from pyecharts import options as opts
from pyecharts.charts import Grid, Line, Scatter
# 准备示例数据
x_data = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
y_data_a = [820, 932, 901, 934, 1290, 1330, 1320]
y_data_b = [620, 732, 701, 734, 1090, 1130, 1120]
def make_scatter(title):
return (
Scatter(init_opts=opts.InitOpts(width='500px', height='400px'))
.add_xaxis(x_data)
.add_yaxis("组A", y_data_a, symbol_size=10)
.add_yaxis("组B", y_data_b, symbol_size=10)
.set_global_opts(
title_opts=opts.TitleOpts(title=title),
legend_opts=opts.LegendOpts(pos_left="20%"),
)
)
def make_line(title):
return (
Line(init_opts=opts.InitOpts(width='500px', height='400px'))
.add_xaxis(x_data)
.add_yaxis("组A", y_data_a, is_smooth=True)
.add_yaxis("组B", y_data_b, is_smooth=True)
.set_global_opts(
title_opts=opts.TitleOpts(title=title),
legend_opts=opts.LegendOpts(pos_right="20%"),
)
)
# 水平布局:左侧散点图,右侧折线图
horizontal_grid = (
Grid(init_opts=opts.InitOpts(width='1000px', height='450px'))
.add(make_scatter("散点图 - 左侧"), grid_opts=opts.GridOpts(pos_right="55%"))
.add(make_line("折线图 - 右侧"), grid_opts=opts.GridOpts(pos_left="55%"))
)
# 垂直布局:上方散点图,下方折线图
vertical_grid = (
Grid(init_opts=opts.InitOpts(width='600px', height='800px'))
.add(make_scatter("散点图 - 上方"), grid_opts=opts.GridOpts(pos_bottom="55%"))
.add(make_line("折线图 - 下方"), grid_opts=opts.GridOpts(pos_top="55%"))
)
# 任意布局:两个子图分别占据不同区域
free_grid = (
Grid(init_opts=opts.InitOpts(width='1000px', height='600px'))
.add(make_scatter("散点图 - 左上"), grid_opts=opts.GridOpts(pos_right="50%", pos_bottom="50%"))
.add(make_line("折线图 - 右下"), grid_opts=opts.GridOpts(pos_left="50%", pos_top="50%"))
)
print("已创建 3 种 Grid 布局:水平、垂直、任意位置")
print("每个 Grid 均包含 2 个子图")已创建 3 种 Grid 布局:水平、垂直、任意位置
每个 Grid 均包含 2 个子图1.2 理解 GridOpts 的位置参数
Grid 布局的核心在于 GridOpts 中的 pos_top、pos_bottom、pos_left、pos_right 四个参数。初学者最容易混淆的是:这些参数并非定义子图“位于”哪个方向,而是定义子图“距离”画布对应边界的距离(百分比或像素)。
pos_right="55%":表示子图的右边界距离画布右边界有 55% 的空白。因此,子图实际占据的是画布左侧 45% 的宽度。pos_left="55%":表示子图的左边界距离画布左边界有 55% 的空白。因此,子图实际占据的是画布右侧 45% 的宽度。
1.3 实现水平布局
让我们将散点图放在左侧,折线图放在右侧。
上面代码的第一个 Grid 使用 pos_right="55%" 和 pos_left="55%",将两个子图左右分开:散点图占左侧区域,折线图占右侧区域。
1.4 实现垂直与任意布局
同理,我们可以实现垂直布局(上下排列)或更复杂的任意布局。
vertical_grid 用 pos_bottom 和 pos_top 实现上下排列;free_grid 同时组合左右与上下偏移,让两个子图落入不同象限。调整这四个参数时,始终把它们理解为“子图边界到画布对应边界的留白”,布局结果会更直观。
1.5 Grid 中的数据关联特性
Grid 组件一个非常强大的特性是数据关联。当不同子图中的数据系列具有相同的 series_name(如我们都使用了“组A”和“组B”)时,它们在交互上是联动的。
- 效果:在最终生成的 HTML 页面中,当你用鼠标点击或悬停图例中的“组A”时,两个图表中属于“组A”的数据点会同时高亮或隐藏。这使得对比分析变得非常直观。
- 原理:pyecharts 在底层生成 ECharts 配置时,会识别相同的系列名,并配置相应的
legend联动。 - 控制:如果你不希望图表间联动,只需为不同图表中的系列设置不同的名称即可。
2. Page:自适应与可拖拽的页面组件
Page 组件提供了一种更简单的多图表组织方式。你无需关心每个图表的具体位置,只需将它们添加到 Page 中,并指定一个布局策略,Page 会自动排列它们。
2.1 SimplePageLayout:简单自适应布局
SimplePageLayout 会根据你为每个子图设置的宽度 (width) 和页面容器的实际宽度,自动决定是水平排列(并排)还是垂直排列(换行)。注意:Page 的完整布局效果需要在保存为 HTML 文件并在浏览器中打开后才能完全呈现。
from pyecharts import options as opts
from pyecharts.charts import Line, Page, Scatter
x_data = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
y_data_a = [820, 932, 901, 934, 1290, 1330, 1320]
# 每个子图都重新创建,避免依赖上一个代码块中的局部变量
scatter_small = (
Scatter(init_opts=opts.InitOpts(width='400px', height='300px'))
.add_xaxis(x_data)
.add_yaxis("组A", y_data_a)
.set_global_opts(title_opts=opts.TitleOpts(title="散点图"))
)
line_small = (
Line(init_opts=opts.InitOpts(width='400px', height='300px'))
.add_xaxis(x_data)
.add_yaxis("组A", y_data_a, is_smooth=True)
.set_global_opts(title_opts=opts.TitleOpts(title="折线图"))
)
# 方式一:SimplePageLayout 自适应排列
simple_page = Page(layout=Page.SimplePageLayout)
simple_page.add(scatter_small, line_small)
simple_page.render("simple_page_layout.html")
# 方式二:DraggablePageLayout 可拖拽排列
draggable_page = Page(layout=Page.DraggablePageLayout)
draggable_page.add(scatter_small, line_small)
draggable_page.render("draggable_page_layout.html")
print("已生成两种 Page 页面:simple_page_layout.html 与 draggable_page_layout.html")
print("SimplePageLayout 会按容器宽度自动换行;DraggablePageLayout 可在浏览器中拖动图表")已生成两种 Page 页面:simple_page_layout.html 与 draggable_page_layout.html
SimplePageLayout 会按容器宽度自动换行;DraggablePageLayout 可在浏览器中拖动图表2.2 DraggablePageLayout:可拖拽布局
DraggablePageLayout 提供了一个交互性更强的功能:允许用户在浏览器中自由拖拽图表来调整布局,并且可以将最终的布局保存下来。
上面的同一个代码块已经同时生成 draggable_page_layout.html。在浏览器中打开后,你可以拖动图表调整位置;点击页面上的“保存配置”会下载布局 JSON(默认文件名为 chart_config.json)。
将该 JSON 与 HTML 放在同一工作目录后,可使用 pyecharts 2.1.0 的实际接口恢复布局:
Page.save_resize_html(
source="draggable_page_layout.html",
cfg_file="chart_config.json",
dest="fixed_layout.html"
)这会生成应用固定布局的新文件 fixed_layout.html;Page 类没有 load_resize_json() 方法。
3. Tab:节省空间的分页组件
Tab 组件通过标签页的形式来组织多个图表。它非常节省空间,因为同一时间只显示一个图表,用户通过点击标签来切换。这适用于图表数量较多,且不需要同时对比查看的场景。
from pyecharts import options as opts
from pyecharts.charts import Line, Scatter, Tab
x_data = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
y_data_a = [820, 932, 901, 934, 1290, 1330, 1320]
scatter_tab = (
Scatter(init_opts=opts.InitOpts(width='500px', height='350px'))
.add_xaxis(x_data)
.add_yaxis("组A", y_data_a)
.set_global_opts(title_opts=opts.TitleOpts(title="散点图"))
)
line_tab = (
Line(init_opts=opts.InitOpts(width='500px', height='350px'))
.add_xaxis(x_data)
.add_yaxis("组A", y_data_a, is_smooth=True)
.set_global_opts(title_opts=opts.TitleOpts(title="折线图"))
)
# 创建 Tab 组件
tab = Tab()
# 向 Tab 中添加图表,并指定标签页的名称
tab.add(scatter_tab, "散点图")
tab.add(line_tab, "折线图")
print("Tab 组件已创建,包含 2 个标签页。")
print("标签页名称: '散点图', '折线图'")
print("在渲染出的页面中,可通过点击顶部标签进行切换。")Tab 组件已创建,包含 2 个标签页。
标签页名称: '散点图', '折线图'
在渲染出的页面中,可通过点击顶部标签进行切换。📝 动手练一练
- 布局挑战:使用
Grid组件,尝试将三个不同的图表(例如,一个柱状图、一个折线图、一个饼图)布局成一个“品”字形(上面一个,下面两个并排)。请写出关键的GridOpts参数设置思路。
点击查看参考答案
思路:
- 假设画布总宽度为
100%,高度为100%。 - 顶部图表:占据上半部分,例如设置
pos_bottom="55%"(图表下边界距画布底55%),即图表高度约占45%。同时,为了居中,可以设置pos_left="20%", pos_right="20%",使其宽度占60%。 - 左下图表:占据左下角。设置
pos_top="55%"(图表上边界距画布顶55%,即从45%高度处开始),pos_right="55%"(图表右边界距画布右55%,即宽度占左45%)。 - 右下图表:占据右下角。设置
pos_top="55%",pos_left="55%"(图表左边界距画布左55%,即宽度占右45%)。
关键参数示例:
# 伪代码示意
grid = Grid()
grid.add(bar_chart, grid_opts=opts.GridOpts(pos_bottom="55%", pos_left="20%", pos_right="20%"))
grid.add(line_chart, grid_opts=opts.GridOpts(pos_top="55%", pos_right="55%"))
grid.add(pie_chart, grid_opts=opts.GridOpts(pos_top="55%", pos_left="55%"))- 数据关联实验:创建两个
Line图表,第一个图表包含系列“销售额”和“成本”,第二个图表包含系列“销售额”和“利润率”。将它们用Grid组合后,在交互时观察哪个系列会联动?为什么?
点击查看参考答案
答案:只有“销售额”这个系列会联动。
原因:Grid 的数据关联是基于相同的 series_name。在这个例子中:
- 图表1的系列名:
"销售额","成本" - 图表2的系列名:
"销售额","利润率"只有"销售额"这个名称在两个图表中都存在。因此,当点击图例操作“销售额”时,两个图表中对应的“销售额”线条会同时高亮或隐藏。而“成本”和“利润率”因为名称唯一,只影响其所在的图表。
本章小结
本节我们学习了 pyecharts 中用于构建组合图表的三个核心组件,它们各有其适用的场景:
Grid:当你需要对图表位置进行像素级精确控制,或者需要图表间数据联动时,它是首选。适用于制作严谨的分析报告或数据大屏中的固定布局模块。Page:当你需要快速生成一个包含多个图表的自适应页面,或者希望提供交互式布局能力(如让用户自行拖拽排列)时,它非常方便。常用于生成可分享的数据看板。Tab:当图表数量较多,且屏幕空间有限,不需要同时展示所有图表时,使用Tab可以保持界面整洁,用户按需切换查看。
📋 行动清单
- 使用
Grid组件,将你之前项目中生成的至少两个关联图表组合在一起,并调整到一个合理的布局。 - 尝试使用
Page组件的DraggablePageLayout,创建一个包含3-4个图表的小型看板,并在浏览器中体验拖拽布局功能。 - 思考你的某个数据分析结果,如果图表超过5个,考虑如何使用
Tab组件来组织它们,并写出大致的代码结构。
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
