Github仓库:点击跳转
PyEcharts是ECharts的Python封装库,用于生成交互式图表。与Matplotlib的静态图不同,PyEcharts支持工具栏缩放、数据区域缩放、图表切换等丰富的交互功能。
8.1 工具介绍
8.1.1 PyEcharts概述
PyEcharts是Apache ECharts的Python接口,通过简洁的API封装,支持生成超过20种交互式图表类型。相比Matplotlib的静态输出,PyEcharts生成的图表支持鼠标悬停提示、数据区域缩放、图表切换等交互功能,非常适合在Jupyter Notebook和HTML报告中展示。
# 基础导入
from pyecharts import options as opts
from pyecharts.charts import Line, Bar, Pie, Scatter, HeatMap, Grid, Page, Tab, Timeline
# 渲染方式
chart.render_notebook() # 在Jupyter中渲染
chart.render("chart.html") # 输出为HTML文件8.1.2 核心概念
8.1.3 InitOpts 初始化配置
opts.InitOpts(
width="800px", # 图表宽度
height="400px", # 图表高度
theme=ThemeType.LIGHT, # 主题风格
page_title="图表", # HTML页面标题
js_host="https://cdn.jsdelivr.net/npm/echarts@" # JS文件CDN地址
)8.1.4 TitleOpts 标题配置
opts.TitleOpts(
title="主标题", # 图表主标题
subtitle="副标题", # 副标题
pos_left="center", # 标题位置:left/center/right 或百分比
pos_top="10%", # 标题距离顶部的位置
title_textstyle_opts=opts.TextStyleOpts(color="#333", font_size=16)
)8.1.5 AxisOpts 坐标轴配置
opts.AxisOpts(
name="轴名称", # 坐标轴名称
type_="category", # 轴类型:category/value/time/log
data=None, # 分类数据(type_=category时使用)
axislabel_opts=opts.LabelOpts(rotate=45), # 标签旋转角度
name_textstyle_opts=opts.TextStyleOpts(font_size=12)
)8.1.6 TooltipOpts 提示框配置
opts.TooltipOpts(
trigger="item", # 触发类型:item/axis/none
trigger_on="mousemove", # 触发时机:mousemove/click
formatter=None, # 格式化字符串或函数
background_color="#fff", # 背景色
border_color="#333", # 边框色
text_style_opts=opts.TextStyleOpts(color="#333")
)8.2 基础图表函数详解
8.2.1 Line 折线图
Line(init_opts=opts.InitOpts())
.add_xaxis(xaxis_data) # 添加X轴数据
.add_yaxis(series_name, y_data, # 添加Y轴数据系列
markline_opts=None, # 标记线配置
markpoint_opts=None, # 标记点配置
linestyle_opts=None, # 线条样式
label_opts=None) # 标签配置
.set_global_opts(...) # 设置全局配置
.set_series_opts(...) # 设置系列配置add_xaxis 参数:
add_yaxis 参数:
8.2.2 Bar 柱状图
Bar(init_opts=opts.InitOpts())
.add_xaxis(xaxis_data)
.add_yaxis(series_name, y_data,
category_gap="30%", # 分类间距
bar_max_width=None, # 最大柱宽
itemstyle_opts=None, # 条形样式
label_opts=None)
.set_global_opts(...)
.set_series_opts(...)add_yaxis 参数:
8.2.3 Pie 饼图
Pie(init_opts=opts.InitOpts())
.add(
series_name="", # 系列名称
data_pair=[["A", 100], ["B", 200]], # 数据对
radius=["30%", "70%"], # 半径:[内径,外径]
center=["50%", "50%"], # 圆心位置
rosetype="radius", # 玫瑰图类型:radius/area
label_opts=None) # 标签配置
.set_global_opts(...)
.set_series_opts(...)add 参数:
8.2.4 Scatter 散点图
Scatter(init_opts=opts.InitOpts())
.add_xaxis(xaxis_data)
.add_yaxis(series_name, y_data,
symbol_size=10, # 符号大小
symbol=None, # 符号形状
label_opts=None)
.set_global_opts(...)
.set_series_opts(...)8.2.5 HeatMap 热力图
HeatMap(init_opts=opts.InitOpts())
.add_xaxis(xaxis_data)
.add_yaxis(yaxis_data)
.add_yaxis(series_name, data, value_min=None, value_max=None)
.set_global_opts(
visualmap_opts=opts.VisualMapOpts(min_=0, max_=1),
tooltip_opts=opts.TooltipOpts(trigger="item"))8.2.6 Radar 雷达图
Radar(init_opts=opts.InitOpts())
.add_schema(
schema=[opts.RadarIndicatorItem(name, max_), ...], # 指示器配置
shape="polygon", # 形状:polygon/circle
split_number=5, # 分隔区域数
splitline_opt=None, # 分割线样式
splitarea_opt=None) # 分隔区域样式
.add(series_name, data, color=None)
.set_global_opts(...)8.2.7 WordCloud 词云
WordCloud(init_opts=opts.InitOpts())
.add(series_name, data,
word_size_range=[12, 60], # 词云字体大小范围
shape="circle", # 形状:circle/cardio/diamond/star
word_gap=20, # 词间距
text_style_opts=None)
.set_global_opts(...)8.3 组合组件详解
8.3.1 Grid 网格布局
Grid用于在同一个坐标系中实现多图表的精确布局。
Grid(init_opts=opts.InitOpts())
.add(chart, grid_opts=opts.GridOpts(
pos_top="10%", pos_bottom="50%",
pos_left="5%", pos_right="5%",
grid_gap=10))
.add(chart2, grid_opts=opts.GridOpts(
pos_top="55%", pos_bottom="5%",
pos_left="5%", pos_right="5%"))GridOpts 参数:
8.3.2 Page 分页展示
Page组件将多个图表添加到同一个HTML页面中。
page = Page(layout=Page.SimplePageLayout)
page.add(chart1, chart2, chart3)
page.render("page.html")8.3.3 Tab 标签页切换
Tab通过标签页形式展示多个图表。
tab = Tab()
tab.add(chart1, "图表1标题")
tab.add(chart2, "图表2标题")
tab.render("tab.html")8.3.4 Timeline 时间线
Timeline按时间顺序展示数据变化,支持自动播放。
tl = Timeline(init_opts=opts.InitOpts())
tl.add_schema(
play_interval=2000, # 播放间隔(毫秒)
is_auto_play=True, # 是否自动播放
is_loop_play=True, # 是否循环播放
is_reverse=False, # 是否反向播放
orient="horizontal", # 方向:horizontal/vertical
symbol="emptyCircle", # 时间点标记形状
symbol_size=8) # 标记大小
tl.add(chart, "时间标签")add_schema 参数:
8.4 高级图表函数详解
8.4.1 Gauge 仪表盘
Gauge(init_opts=opts.InitOpts())
.add(
series_name="指标", # 系列名称
data_pair=[("指标名", 85)], # 数据对
split_number=10, # 分隔段数
itemstyle_opts=None) # 样式配置
.set_global_opts(...)8.4.2 Liquid 水球图
Liquid(init_opts=opts.InitOpts())
.add(
series_name="进度", # 系列名称
data=[0.78], # 数据(0-1之间)
is_animation=True, # 是否动画
color=None) # 颜色
.set_global_opts(...)8.4.3 Sunburst 旭日图
Sunburst(init_opts=opts.InitOpts())
.add(
series_name="", # 系列名称
data=data, # 层级数据
radius=["0%", "100%"], # 半径范围
levels=None) # 层级配置
.set_global_opts(...)8.4.4 EffectScatter 涟漪散点图
EffectScatter(init_opts=opts.InitOpts())
.add_xaxis(xaxis_data)
.add_yaxis(series_name, y_data,
symbol=None, symbol_size=None)
.set_series_opts(
effect_opts=opts.EffectOpts(scale=3, period=2, color=None))
.set_global_opts(...)EffectOpts 参数:
8.5 数据缩放组件
8.5.1 DataZoomOpts 数据区域缩放
opts.DataZoomOpts(
range_start=0, # 起始位置(%)
range_end=100, # 结束位置(%)
orient="horizontal", # 方向
pos_top="85%", # 位置
type_="slider") # 类型:slider/inside8.6 样式配置详解
8.6.1 LabelOpts 标签配置
opts.LabelOpts(
is_show=True, # 是否显示标签
position="top", # 位置:top/bottom/left/right/inside
formatter=None, # 格式化函数或字符串
font_size=12, # 字体大小
font_style="normal", # 字体样式:normal/italic/oblique
font_weight="normal", # 字体粗细:normal/bold/bolder/lighter
color="#333") # 字体颜色8.6.2 ItemStyleOpts 数据项样式
opts.ItemStyleOpts(
color=None, # 填充颜色
color0=None, # 备用颜色
border_color=None, # 边框颜色
border_width=0, # 边框宽度
opacity=1) # 透明度(0-1)8.6.3 LineStyleOpts 线样式
opts.LineStyleOpts(
width=1, # 线宽
color=None, # 颜色
type_="solid", # 类型:solid/dashed/dotted
opacity=1) # 透明度8.7 主题配置
PyEcharts支持通过ThemeType指定内置主题。
from pyecharts.globals import ThemeType
opts.InitOpts(theme=ThemeType.LIGHT) # 明亮主题
opts.InitOpts(theme=ThemeType.DARK) # 暗黑主题
opts.InitOpts(theme=ThemeType.MACARONS) # 马卡龙主题可用主题列表:
本教程涵盖基础图表、组合布局和主题配置,重点讲解如何使用Grid组件实现多图表的合理布局。
8.8 基础图表
PyEcharts提供了丰富的基础图表类型。
折线图(Line)
折线图用于展示数据随时间或其他连续变量变化的趋势。
from pyecharts.charts import Line
from pyecharts import options as opts
# 折线图:2015年月平均气温趋势
line = (
Line(init_opts=opts.InitOpts(width="800px", height="400px"))
.add_xaxis(monthly_temp.index.tolist())
.add_yaxis("最高气温", monthly_temp['temp_max'].round(1).tolist(),
markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]))
.add_yaxis("最低气温", monthly_temp['temp_min'].round(1).tolist(),
markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="min")]))
.set_global_opts(
title_opts=opts.TitleOpts(title="2015年月平均气温趋势", subtitle="单位:摄氏度"),
xaxis_opts=opts.AxisOpts(name="月份"),
yaxis_opts=opts.AxisOpts(name="气温 (°C)"),
tooltip_opts=opts.TooltipOpts(trigger="axis")
)
)
line.render_notebook()柱状图(Bar)
柱状图适合展示分类数据之间的对比关系。
from pyecharts.charts import Bar
# 柱状图:各岛屿企鹅数量
bar = (
Bar(init_opts=opts.InitOpts(width="700px", height="400px"))
.add_xaxis(island_counts.index.tolist())
.add_yaxis("数量", island_counts.values.tolist())
.set_global_opts(
title_opts=opts.TitleOpts(title="各岛屿企鹅数量"),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=0)),
yaxis_opts=opts.AxisOpts(name="数量"),
tooltip_opts=opts.TooltipOpts(trigger="axis")
)
.set_series_opts(
label_opts=opts.LabelOpts(position="top"),
itemstyle_opts=opts.ItemStyleOpts(color="#4ECDC4")
)
)
bar.render_notebook()饼图(Pie)
饼图适合展示各分类占总体的比例关系。
from pyecharts.charts import Pie
# 饼图:天气类型分布
pie = (
Pie(init_opts=opts.InitOpts(width="600px", height="400px"))
.add(
"",
[list(z) for z in zip(weather_counts.index.tolist(), [int(x) for x in weather_counts.values.tolist()])],
radius=["30%", "70%"],
label_opts=opts.LabelOpts(formatter="{b}: {d}%")
)
.set_global_opts(
title_opts=opts.TitleOpts(title="天气类型分布", pos_left="center"),
legend_opts=opts.LegendOpts(orient="vertical", pos_left="left", pos_top="middle")
)
)
pie.render_notebook()散点图(Scatter)
散点图用于展示两个连续变量之间的关系。
from pyecharts.charts import Scatter
# 散点图:企鹅喙长与喙深关系
scatter_adelie = (
Scatter()
.add_xaxis([float(x) for x in penguins[penguins['species']=='Adelie']['bill_length_mm'].tolist()])
.add_yaxis('Adelie', [float(y) for y in penguins[penguins['species']=='Adelie']['bill_depth_mm'].tolist()])
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
)
scatter_chinstrap = (
Scatter()
.add_xaxis([float(x) for x in penguins[penguins['species']=='Chinstrap']['bill_length_mm'].tolist()])
.add_yaxis('Chinstrap', [float(y) for y in penguins[penguins['species']=='Chinstrap']['bill_depth_mm'].tolist()])
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
)
scatter_gentoo = (
Scatter()
.add_xaxis([float(x) for x in penguins[penguins['species']=='Gentoo']['bill_length_mm'].tolist()])
.add_yaxis('Gentoo', [float(y) for y in penguins[penguins['species']=='Gentoo']['bill_depth_mm'].tolist()])
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
)
# 叠加所有系列
scatter_chart = scatter_adelie
for s in [scatter_chinstrap, scatter_gentoo]:
scatter_chart = scatter_chart.overlap(s)
scatter_chart.set_global_opts(
title_opts=opts.TitleOpts(title="企鹅喙长与喙深关系"),
xaxis_opts=opts.AxisOpts(name="喙长 (mm)"),
yaxis_opts=opts.AxisOpts(name="喙深 (mm)"),
legend_opts=opts.LegendOpts(pos_left="right"),
tooltip_opts=opts.TooltipOpts(trigger="item")
)
scatter_chart.render_notebook()8.9 使用真实数据的图表
城市房价对比
# 处理房价数据:各城市平均单价
house_clean = house.dropna(subset=['unit'])
house_clean = house_clean[house_clean['unit'].str.contains('元')]
house_clean['price_num'] = house_clean['unit'].str.extract(r'(\d+)').astype(float)
city_price = house_clean.groupby('province')['price_num'].mean().sort_values(ascending=True).tail(10)
bar2 = (
Bar(init_opts=opts.InitOpts(width="850px", height="450px"))
.add_xaxis(city_price.index.tolist())
.add_yaxis("平均单价", [round(x, 0) for x in city_price.values.tolist()], category_gap="50%")
.set_global_opts(
title_opts=opts.TitleOpts(title="各省份房产均价对比 (TOP 10)"),
xaxis_opts=opts.AxisOpts(name="省份", axislabel_opts=opts.LabelOpts(rotate=30)),
yaxis_opts=opts.AxisOpts(name="单价 (元/㎡)"),
tooltip_opts=opts.TooltipOpts(trigger="axis")
)
.set_series_opts(
label_opts=opts.LabelOpts(position="top"),
itemstyle_opts=opts.ItemStyleOpts(color="#FF6B6B")
)
)
bar2.render_notebook()热力图
from pyecharts.charts import HeatMap
# 热力图:企鹅身体指标相关性
num_cols = ["bill_length_mm", "bill_depth_mm", "flipper_length_mm", "body_mass_g"]
corr = penguins[num_cols].corr()
hm = (
HeatMap(init_opts=opts.InitOpts(width="700px", height="500px"))
.add_xaxis(corr.columns.tolist())
.add_yaxis(
"",
corr.index.tolist(),
[[i, j, round(corr.iloc[i, j], 2)] for i in range(len(corr)) for j in range(len(corr))]
)
.set_global_opts(
title_opts=opts.TitleOpts(title="企鹅身体指标相关性热力图"),
visualmap_opts=opts.VisualMapOpts(min_=-1, max_=1, is_calculable=True),
tooltip_opts=opts.TooltipOpts(trigger="item")
)
)
hm.render_notebook()8.10 Grid组合布局
重要: Grid组件是实现多图表合理布局的核心工具。通过设置pos_top、pos_bottom、pos_left、pos_right等参数(使用百分比),可以精确控制每个图表在容器中的位置,避免元素重叠。
Grid上下布局
from pyecharts.charts import Line, Bar, Grid
# Grid 上下布局
line_g = (
Line(init_opts=opts.InitOpts(width="850px", height="300px"))
.add_xaxis(["1月", "2月", "3月", "4月", "5月", "6月"])
.add_yaxis("蒸发量", [50, 70, 90, 120, 150, 180])
.add_yaxis("降水量", [60, 80, 100, 130, 160, 200])
.set_global_opts(
title_opts=opts.TitleOpts(title="气象数据对比", subtitle="2015年月度统计", pos_left="center", pos_top="0%"),
tooltip_opts=opts.TooltipOpts(trigger="axis")
)
)
bar_g = (
Bar(init_opts=opts.InitOpts(width="850px", height="280px"))
.add_xaxis(["1月", "2月", "3月", "4月", "5月", "6月"])
.add_yaxis("蒸发量", [50, 70, 90, 120, 150, 180])
.add_yaxis("降水量", [60, 80, 100, 130, 160, 200])
.set_series_opts(
label_opts=opts.LabelOpts(position="top"),
itemstyle_opts=opts.ItemStyleOpts(color="#45B7D1")
)
)
grid = (
Grid(init_opts=opts.InitOpts(width="900px", height="800px"))
.add(line_g, grid_opts=opts.GridOpts(pos_top="10%", pos_bottom="52%", pos_left="5%", pos_right="5%"))
.add(bar_g, grid_opts=opts.GridOpts(pos_top="55%", pos_bottom="10%", pos_left="5%", pos_right="5%"))
)
grid.render_notebook()Grid左右布局
from pyecharts.charts import Scatter, Bar, Grid
# 左侧散点图
scatter_left = (
Scatter()
.add_xaxis([10, 20, 30, 40, 50])
.add_yaxis("A组", [20, 30, 40, 50, 60], xaxis_index=0, yaxis_index=0)
.add_yaxis("B组", [30, 40, 50, 60, 70], xaxis_index=0, yaxis_index=0)
.set_global_opts(
title_opts=opts.TitleOpts(title="分组对比", pos_left="10%"),
xaxis_opts=opts.AxisOpts(type_="value", name="指标"),
yaxis_opts=opts.AxisOpts(type_="value", name="数值")
)
)
# 右侧柱状图
bar_right = (
Bar()
.add_xaxis(["A组", "B组", "C组"])
.add_yaxis("数值", [45, 55, 48], xaxis_index=1, yaxis_index=1)
.set_series_opts(label_opts=opts.LabelOpts(position="top"))
.set_global_opts(
title_opts=opts.TitleOpts(title="分组统计", pos_left="62%"),
xaxis_opts=opts.AxisOpts(type_="category"),
yaxis_opts=opts.AxisOpts(name="数值")
)
)
# Grid 布局
grid_lr = (
Grid(init_opts=opts.InitOpts(width="980px", height="500px"))
.add(
scatter_left,
grid_opts=opts.GridOpts(pos_left="8%", pos_right="55%", pos_top="18%", pos_bottom="14%"),
is_control_axis_index=True
)
.add(
bar_right,
grid_opts=opts.GridOpts(pos_left="60%", pos_right="8%", pos_top="18%", pos_bottom="14%"),
is_control_axis_index=True
)
)
grid_lr.render_notebook()Grid四宫格仪表盘
from pyecharts.charts import Bar, Line, Scatter, Pie, Grid
# 左上:柱状图
bar1 = (
Bar()
.add_xaxis(["衬衫", "毛衣", "裙子", "裤子", "风衣"])
.add_yaxis("数量", [20, 30, 40, 35, 25], xaxis_index=0, yaxis_index=0)
.add_yaxis("库存", [50, 40, 30, 45, 55], xaxis_index=0, yaxis_index=0)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="服装销量", pos_left="8%", pos_top="3%"),
xaxis_opts=opts.AxisOpts(type_="category"),
yaxis_opts=opts.AxisOpts(type_="value")
)
)
# 右上:折线图
line1 = (
Line()
.add_xaxis(["周一", "周二", "周三", "周四", "周五"])
.add_yaxis("销量", [120, 200, 150, 80, 70], xaxis_index=1, yaxis_index=1)
.add_yaxis("访问量", [300, 350, 280, 400, 380], xaxis_index=1, yaxis_index=1)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="访问趋势", pos_left="58%", pos_top="3%"),
xaxis_opts=opts.AxisOpts(type_="category"),
yaxis_opts=opts.AxisOpts(type_="value")
)
)
# 左下:散点图
scatter1 = (
Scatter()
.add_xaxis(["A", "B", "C", "D", "E"])
.add_yaxis("数据", [50, 60, 70, 80, 90], xaxis_index=2, yaxis_index=2)
.set_series_opts(symbol_size=14)
.set_global_opts(
title_opts=opts.TitleOpts(title="数据分布", pos_left="8%", pos_top="53%"),
xaxis_opts=opts.AxisOpts(type_="category"),
yaxis_opts=opts.AxisOpts(type_="value")
)
)
# 右下:饼图
pie1 = (
Pie()
.add(
"",
[["北京", 45], ["上海", 35], ["广州", 20]],
center=["75%", "74%"],
radius=["12%", "22%"]
)
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
.set_global_opts(title_opts=opts.TitleOpts(title="城市占比", pos_left="58%", pos_top="53%"))
)
grid4 = (
Grid(init_opts=opts.InitOpts(width="1000px", height="800px"))
.add(bar1, grid_opts=opts.GridOpts(pos_left="8%", pos_right="56%", pos_top="12%", pos_bottom="56%"), is_control_axis_index=True)
.add(line1, grid_opts=opts.GridOpts(pos_left="58%", pos_right="8%", pos_top="12%", pos_bottom="56%"), is_control_axis_index=True)
.add(scatter1, grid_opts=opts.GridOpts(pos_left="8%", pos_right="56%", pos_top="62%", pos_bottom="10%"), is_control_axis_index=True)
.add(pie1, grid_opts=opts.GridOpts(pos_left="58%", pos_right="8%", pos_top="62%", pos_bottom="10%"))
)
grid4.render_notebook()叠加图表:折线+柱状混合
from pyecharts.charts import Line, Bar
overlap_base = (
Bar(init_opts=opts.InitOpts(width="800px", height="450px"))
.add_xaxis(["周一", "周二", "周三", "周四", "周五", "周六", "周日"])
.add_yaxis("咖啡销量", [120, 150, 90, 180, 200, 250, 280])
.add_yaxis("茶销量", [80, 60, 100, 70, 90, 120, 110])
.set_series_opts(label_opts=opts.LabelOpts(position="top"))
)
line_overlay = (
Line()
.add_xaxis(["周一", "周二", "周三", "周四", "周五", "周六", "周日"])
.add_yaxis("总利润", [200, 210, 190, 250, 290, 370, 390])
.set_series_opts(
linestyle_opts=opts.LineStyleOpts(width=3, color="#FF6B6B"),
label_opts=opts.LabelOpts(is_show=True, position="top")
)
)
overlap_chart = overlap_base.overlap(line_overlay)
overlap_chart.set_global_opts(
title_opts=opts.TitleOpts(title="饮品销量与利润对比"),
tooltip_opts=opts.TooltipOpts(trigger="axis")
)
overlap_chart.render_notebook()8.11 组合组件
Page - 多图表分页
Page组件允许将多个图表放在同一个页面中。
from pyecharts.charts import Page
page = Page(layout=Page.SimplePageLayout)
line_p = (
Line()
.add_xaxis(["1月", "2月", "3月", "4月"])
.add_yaxis("产品A", [100, 120, 130, 150])
.add_yaxis("产品B", [80, 90, 100, 110])
.set_global_opts(title_opts=opts.TitleOpts(title="产品销售趋势"))
)
bar_p = (
Bar()
.add_xaxis(["手机", "电脑", "平板", "耳机"])
.add_yaxis("销量", [300, 450, 200, 150])
.add_yaxis("库存", [100, 200, 300, 250])
.set_global_opts(title_opts=opts.TitleOpts(title="电子产品销售统计"))
)
pie_p = (
Pie()
.add("", [["已完成", 60], ["进行中", 30], ["未开始", 10]], radius=["40%", "70%"])
.set_global_opts(title_opts=opts.TitleOpts(title="项目进度"))
)
page.add(line_p, bar_p, pie_p)
page.render_notebook()Tab - 标签页切换
Tab组件通过标签页的形式展示多个图表。
from pyecharts.charts import Tab
tab = Tab()
line_tab = (
Line()
.add_xaxis(["周一", "周二", "周三", "周四", "周五"])
.add_yaxis("本周", [120, 140, 150, 170, 190])
.add_yaxis("上周", [100, 110, 120, 130, 140])
.set_global_opts(title_opts=opts.TitleOpts(title="销售趋势对比"))
)
bar_tab = (
Bar()
.add_xaxis(["北京", "上海", "广州", "深圳"])
.add_yaxis("销售额", [5000, 6000, 4500, 5500])
.add_yaxis("利润", [1500, 1800, 1200, 1600])
.set_global_opts(title_opts=opts.TitleOpts(title="城市销售对比"))
)
pie_tab = (
Pie()
.add("", [["已完成", 60], ["进行中", 30], ["未开始", 10]], radius=["40%", "70%"])
.set_global_opts(title_opts=opts.TitleOpts(title="项目进度"))
)
tab.add(line_tab, "趋势图")
tab.add(bar_tab, "对比图")
tab.add(pie_tab, "进度图")
tab.render_notebook()Timeline - 时间线动画
Timeline组件允许按时间顺序展示数据的变化。
from pyecharts.charts import Timeline
tl = Timeline(init_opts=opts.InitOpts(width="800px", height="400px"))
tl.add_schema(
play_interval=2000, # 播放间隔 2 秒
is_auto_play=True, # 自动播放
is_loop_play=True # 循环播放
)
for year in [2013, 2014, 2015]:
line_t = (
Line()
.add_xaxis(["1月", "2月", "3月", "4月"])
.add_yaxis("销量", [100 + year * 10, 120 + year * 10, 130 + year * 10, 150 + year * 10])
.add_yaxis("利润", [80 + year * 8, 90 + year * 8, 100 + year * 8, 120 + year * 8])
.set_global_opts(title_opts=opts.TitleOpts(title=f"{year}年销售数据", pos_left="center"))
)
tl.add(line_t, f"{year}年")
tl.render_notebook()8.12 高级图表
雷达图(Radar)
雷达图适合展示多维度数据的综合对比。
from pyecharts.charts import Radar
radar = (
Radar(init_opts=opts.InitOpts(width="700px", height="500px"))
.add_schema(
schema=[
opts.RadarIndicatorItem(name="经济", max_=100),
opts.RadarIndicatorItem(name="交通", max_=100),
opts.RadarIndicatorItem(name="环境", max_=100),
opts.RadarIndicatorItem(name="教育", max_=100),
opts.RadarIndicatorItem(name="医疗", max_=100)
],
splitline_opt=opts.SplitLineOpts(is_show=True),
splitarea_opt=opts.SplitAreaOpts(is_show=True)
)
.add("北京", [[85, 90, 80, 75, 88]], color="#1f77b4")
.add("上海", [[90, 85, 85, 80, 86]], color="#ff7f0e")
.set_global_opts(title_opts=opts.TitleOpts(title="城市发展雷达图"))
)
radar.render_notebook()词云(WordCloud)
词云适合展示文本数据中高频关键词的可视化。
from pyecharts.charts import WordCloud
words = [
("Python", 10000), ("数据分析", 8000), ("机器学习", 7500),
("可视化", 6000), ("Pandas", 5500), ("PyEcharts", 5000),
("NumPy", 4500), ("Scikit-learn", 4000), ("深度学习", 3500),
("TensorFlow", 3000), ("PyTorch", 2800), ("NLP", 2600)
]
wordcloud = (
WordCloud(init_opts=opts.InitOpts(width="800px", height="500px"))
.add("", words, word_size_range=[20, 80], shape="diamond")
.set_global_opts(title_opts=opts.TitleOpts(title="技术关键词词云"))
)
wordcloud.render_notebook()涟漪散点图(EffectScatter)
涟漪散点图带有动态涟漪效果,适合突出显示重点数据。
from pyecharts.charts import EffectScatter
from pyecharts.globals import SymbolType
escatter = (
EffectScatter(init_opts=opts.InitOpts(width="700px", height="400px"))
.add_xaxis(["北京", "上海", "广州", "深圳", "成都", "杭州"])
.add_yaxis("GDP排名", [1, 2, 3, 4, 5, 6], symbol=SymbolType.DIAMOND, symbol_size=20)
.set_series_opts(
label_opts=opts.LabelOpts(is_show=True, position="top"),
effect_opts=opts.EffectOpts(scale=3, period=2, color="#FF6B6B")
)
.set_global_opts(
title_opts=opts.TitleOpts(title="城市GDP排名(涟漪效果)"),
yaxis_opts=opts.AxisOpts(is_inverse=True)
)
)
escatter.render_notebook()水球图(Liquid)
水球图适合展示百分比或进度类的数据。
from pyecharts.charts import Liquid
liquid = (
Liquid(init_opts=opts.InitOpts(width="400px", height="400px"))
.add("完成率", [0.78], is_animation=True, color=["#4ECDC4"])
.set_global_opts(title_opts=opts.TitleOpts(title="项目完成率", pos_left="center"))
)
liquid.render_notebook()仪表盘(Gauge)
仪表盘适合展示单一指标的当前值与目标范围的关系。
from pyecharts.charts import Gauge
gauge = (
Gauge(init_opts=opts.InitOpts(width="500px", height="400px"))
.add("满意度", [("评分", 85)], split_number=10)
.set_global_opts(title_opts=opts.TitleOpts(title="用户满意度评分", pos_left="center"))
)
gauge.render_notebook()旭日图(Sunburst)
旭日图是一种高级饼图,可以展示具有层级关系的数据。
from pyecharts.charts import Sunburst
data = [
{"name": "企鹅", "children": [
{"name": "Adelie", "value": 150},
{"name": "Gentoo", "value": 120},
{"name": "Chinstrap", "value": 68}
]},
{"name": "栖息地", "children": [
{"name": "Torgersen", "value": 50},
{"name": "Biscoe", "value": 100},
{"name": "Dream", "value": 88}
]}
]
sunburst = (
Sunburst(init_opts=opts.InitOpts(width="600px", height="500px"))
.add("", data)
.set_global_opts(title_opts=opts.TitleOpts(title="企鹅分类旭日图", pos_left="center"))
)
sunburst.render_notebook()8.13 主题与样式
PyEcharts支持多种内置主题。
from pyecharts.globals import ThemeType
# 不同主题的折线图示例
themes = [ThemeType.LIGHT, ThemeType.DARK, ThemeType.MACARONS]
for theme in themes:
line_theme = (
Line(init_opts=opts.InitOpts(theme=theme, width="600px", height="300px"))
.add_xaxis(["周一", "周二", "周三", "周四", "周五"])
.add_yaxis("销量", [120, 150, 90, 180, 200])
.add_yaxis("利润", [80, 100, 60, 120, 140])
.set_global_opts(title_opts=opts.TitleOpts(title=f"主题演示: {theme}"))
)
line_theme.render_notebook()可用主题: LIGHT, DARK, ESSOS, WALDEN, CHALK, INFOGRAPHIC, MACARONS, PURPLE_PASSION等
8.14 DataZoom数据区域缩放
DataZoom组件允许用户通过拖拽或滑块来缩放数据区域。
# 数据区域缩放
dates = [f"2024-{i//28+1:02d}-{i%28+1:02d}" for i in range(360)]
values = [100 + i * 0.5 + random.randint(-20, 20) for i in range(360)]
line_zoom = (
Line(init_opts=opts.InitOpts(width="900px", height="400px"))
.add_xaxis(dates)
.add_yaxis("访问量", values)
.set_global_opts(
title_opts=opts.TitleOpts(title="日访问量趋势(可缩放)"),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=45)),
datazoom_opts=opts.DataZoomOpts(
range_start=0,
range_end=30,
orient="horizontal",
pos_top="85%"
),
tooltip_opts=opts.TooltipOpts(trigger="axis")
)
)
line_zoom.render_notebook()8.15 核心组件速查
8.16 Grid防重叠要点
上下布局:上方图表设置
pos_bottom="52%",下方图表设置pos_top="55%"左右布局:左侧图表设置
pos_right="52%",右侧图表设置pos_left="55%"四宫格:每个格子约42-45%,间距约10%,确保
pos_top + pos_bottom < 100%使用grid_gap:增加格子之间的间距
8.17 小结
核心要点回顾:
PyEcharts是ECharts的Python封装,支持丰富的交互功能
基础图表:Line、Bar、Pie、Scatter、HeatMap
组合布局:Grid实现多图表精确定位,避免重叠
组合组件:Page、Tab、Timeline增强展示效果
高级图表:Radar、WordCloud、Gauge、Liquid、Sunburst等
主题:支持LIGHT、DARK、MACARONS等多种内置主题
推荐学习资源:
PyEcharts官方文档:https://pyecharts.org
ECharts官方示例:https://echarts.apache.org/examples/
建议多加练习,将交互式可视化应用到数据分析报告中,制作出更加专业的图表。