pyecharts:中国特色可视化库实战
一、pyecharts 简介
pyecharts 是一个基于 Python 的数据可视化库,它将百度开源的 ECharts JavaScript 图表库进行了 Python 封装,使 Python 开发者能够轻松创建交互式、美观且具有中国特色的数据可视化图表。作为国产可视化工具,pyecharts 在地理信息可视化、中文支持、主题定制等方面具有显著优势,尤其适合中国用户和涉及中国地理、经济数据的可视化场景。
1.1 pyecharts 的特点与优势
- 丰富的图表类型:提供超过 30 种常见图表,包括线图、柱状图、饼图、地图等
- 原生中文支持:完美支持中文字体和标签,无需额外配置
- 地理信息可视化:内置完整的中国地图(省级、市级、区/县级)及全球地图
- 强大的交互性:支持缩放、平移、数据筛选、工具提示等交互功能
- 主题定制:提供多种内置主题,包括具有中国传统色彩的主题
- 多渲染器支持:支持 HTML、图片、Jupyter Notebook 等多种渲染方式
- 数据分析集成:与 NumPy、Pandas 等数据分析库无缝集成
- 动态数据:支持时间轴、动画等动态数据展示方式
1.2 适用场景
pyecharts 特别适合以下场景:
- 地理数据可视化:中国省市区县级地图可视化
- 经济金融分析:股市、基金、经济指标等金融数据展示
- 政府报告与数据:政府工作数据、统计年鉴数据可视化
- 企业报表:销售、运营、用户分析等业务数据图表
- 学术研究:需要中文支持的科研数据可视化
- 媒体图表:新闻、媒体报道中的数据图表制作
1.3 与其他可视化库的比较
特性 | pyecharts | Matplotlib | Plotly | Seaborn |
---|---|---|---|---|
交互性 | 高 | 低 | 高 | 低 |
中文支持 | 原生支持 | 需配置 | 需配置 | 需配置 |
中国地图 | 内置详细地图 | 有限支持 | 有限支持 | 有限支持 |
美观度 | 高 | 中 | 高 | 高 |
学习曲线 | 中等 | 陡峭 | 中等 | 平缓 |
代码简洁性 | 高 | 低 | 中 | 高 |
灵活性 | 高 | 极高 | 高 | 中 |
输出格式 | HTML/图片 | 多种图片 | HTML/图片 | 图片 |
二、安装与环境配置
2.1 安装 pyecharts
# 使用 pip 安装
pip install pyecharts
# 安装最新开发版
pip install -U git+https://github.com/pyecharts/pyecharts.git
2.2 安装地图扩展
# 安装地图扩展
pip install echarts-countries-pypkg
pip install echarts-china-provinces-pypkg
pip install echarts-china-cities-pypkg
pip install echarts-china-counties-pypkg
2.3 配置主题与环境
from pyecharts import options as opts
from pyecharts.globals import ThemeType
# 设置全局主题
from pyecharts.globals import CurrentConfig
CurrentConfig.ONLINE_HOST = "https://cdn.jsdelivr.net/npm/echarts@latest/dist/"
CurrentConfig.GLOBAL_THEME = ThemeType.MACARONS # 设置默认主题
2.4 Jupyter Notebook 配置
# 在 Jupyter Notebook 中的配置
from pyecharts.globals import CurrentConfig, NotebookType
CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB # 或 NotebookType.JUPYTER_NOTEBOOK
三、基础图表类型
3.1 线图与面积图
from pyecharts import options as opts
from pyecharts.charts import Line
import random
# 准备数据
x_data = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
y_data = [random.randint(100, 1000) for _ in range(7)]
y_data2 = [random.randint(100, 1000) for _ in range(7)]
# 创建线图
line = (
Line()
.add_xaxis(x_data)
.add_yaxis("产品A", y_data, is_smooth=True)
.add_yaxis("产品B", y_data2, is_smooth=True)
.set_global_opts(
title_opts=opts.TitleOpts(title="销量趋势", subtitle="上周销量"),
tooltip_opts=opts.TooltipOpts(trigger="axis"),
toolbox_opts=opts.ToolboxOpts(is_show=True),
xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=False),
datazoom_opts=[opts.DataZoomOpts()],
)
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False),
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_="max", name="最大值"),
opts.MarkPointItem(type_="min", name="最小值"),
]
),
)
)
# 渲染图表
line.render("line_chart.html")
3.2 柱状图与条形图
from pyecharts.charts import Bar
from pyecharts import options as opts
# 准备数据
provinces = ["广东", "江苏", "浙江", "山东", "河南", "四川", "湖北"]
values = [10413.24, 9816.39, 6230.79, 7312.90, 5200.25, 4602.16, 4212.32]
# 创建柱状图
bar = (
Bar()
.add_xaxis(provinces)
.add_yaxis("2020年GDP(单位:亿元)", values)
.set_global_opts(
title_opts=opts.TitleOpts(title="2020年部分省份GDP对比"),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
datazoom_opts=[opts.DataZoomOpts()],
toolbox_opts=opts.ToolboxOpts(),
)
.set_series_opts(
label_opts=opts.LabelOpts(is_show=True, position="top"),
)
)
bar.render("bar_chart.html")
3.3 饼图与环形图
from pyecharts.charts import Pie
from pyecharts import options as opts
# 准备数据
provinces = ["广东", "江苏", "浙江", "山东", "河南", "四川", "湖北", "其他"]
values = [10413.24, 9816.39, 6230.79, 7312.90, 5200.25, 4602.16, 4212.32, 30000]
# 创建饼图
pie = (
Pie()
.add(
"",
[list(z) for z in zip(provinces, values)],
radius=["40%", "75%"], # 内外半径,形成环形图
center=["50%", "50%"],
)
.set_global_opts(
title_opts=opts.TitleOpts(title="2020年GDP占比"),
legend_opts=opts.LegendOpts(orient="vertical", pos_left="left"),
tooltip_opts=opts.TooltipOpts(
trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"
),
)
.set_series_opts(
label_opts=opts.LabelOpts(formatter="{b}: {c}亿")
)
)
pie.render("pie_chart.html")
3.4 散点图与气泡图
from pyecharts.charts import Scatter
from pyecharts import options as opts
import random
# 准备数据
x_data = [random.randint(0, 100) for _ in range(30)]
y_data = [random.randint(0, 100) for _ in range(30)]
size_data = [random.randint(10, 50) for _ in range(30)]
# 创建散点图
scatter = (
Scatter()
.add_xaxis(x_data)
.add_yaxis(
"散点数据",
[list(z) for z in zip(y_data, size_data)],
symbol_size=15,
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(
title_opts=opts.TitleOpts(title="散点图示例"),
xaxis_opts=opts.AxisOpts(
type_="value", splitline_opts=opts.SplitLineOpts(is_show=True)
),
yaxis_opts=opts.AxisOpts(
type_="value",
axistick_opts=opts.AxisTickOpts(is_show=True),
splitline_opts=opts.SplitLineOpts(is_show=True),
),
tooltip_opts=opts.TooltipOpts(
formatter="{a} <br/> x: {c0}, y: {c1}, size: {c2}"
),
)
)
scatter.render("scatter_chart.html")
四、中国地理信息可视化
4.1 全国地图与省级地图
from pyecharts.charts import Map
from pyecharts import options as opts
# 省份数据
provinces_data = [
("北京", 99),
("上海", 199),
("广东", 299),
("四川", 199),
("台湾", 99),
("山东", 249),
("江苏", 279),
("河北", 165),
("浙江", 259),
("安徽", 155),
("福建", 168),
("江西", 148),
("湖南", 189),
("贵州", 125),
("云南", 145),
("新疆", 80),
("西藏", 50),
]
# 全国地图
c = (
Map()
.add("2020年GDP指数", provinces_data, "china")
.set_global_opts(
title_opts=opts.TitleOpts(title="中国省份GDP指数地图"),
visualmap_opts=opts.VisualMapOpts(
min_=50, max_=300, is_piecewise=True,
pieces=[
{
"min": 250, "label": ">250", "color": "#5f4b8b"},
{
"min": 200, "max": 250, "label": "200-250", "color": "#7a6baa"},
{
"min": 150, "max": 200, "label": "150-200", "color": "#a397cc"},
{
"min": 100, "max": 150, "label": "100-150", "color": "#c7bfe0"},
{
"min": 50, "max": 100, "label": "50-100", "color": "#e0daf1"},
],
),
)
)
c.render("china_map.html")
4.2 省市区县级联动地图
from pyecharts.charts import Map, Geo
from pyecharts import options as opts
from pyecharts.globals import ChartType, SymbolType
# 广东省地级市数据
guangdong_city_data = [
("广州市", 150),
("深圳市", 180),
("珠海市", 70),
("汕头市", 60),
("佛山市", 100),
("韶关市", 40),
("湛江市", 60),
("肇庆市", 50),
("江门市", 60),
("茂名市", 55),
("惠州市", 65),
("梅州市", 40),
("汕尾市", 35),
("河源市", 45),
("阳江市", 40),
("清远市", 45),
("东莞市", 120),
("中山市", 75),
("潮州市", 45),
("揭阳市", 55),
("云浮市", 35),
]
# 广东省地图
map_guangdong = (
Map()
.add("城市GDP", guangdong_city_data, "广东")
.set_global_opts(
title_opts=opts.TitleOpts(title="广东省城市GDP指数地图"),
visualmap_opts=opts.VisualMapOpts(
min_=30, max_=180,
range_text=["高", "低"],
is_calculable=True,
range_color=["lightskyblue", "yellow", "orangered"],
),
)
)
map_guangdong.render("guangdong_map.html")
4.3 地理坐标系与标记点
from pyecharts.charts import Geo
from pyecharts import options as opts
from pyecharts.globals import ChartType, SymbolType
# 城市坐标数据
city_coordinates = {
"北京": [116.407526, 39.90403],
"上海": [121.473701, 31.230416],
"广州": [113.264434, 23.129162],
"深圳": [114.085947, 22.547],
"成都": [104.066541, 30.572269],
"杭州": [120.152791, 30.267446],
"南京": [118.796877, 32.060255],
"武汉": [114.305392, 30.593098],
"西安": [108.946465, 34.347269],
"重庆": [106.551556, 29.563009],
"青岛": [120.382639, 36.067082],
"长沙": [112.938814, 28.228209],
"厦门": [118.089425, 24.479833],
"哈尔滨": [126.535797, 45.802158],
}
# 城市之间的连线数据
lines_data = [
("北京", "上海"),
("北京", "广州"),
("广州", "上海"),
("广州", "成都"),
("上海", "南京"),
("南京", "武汉"),
("武汉", "重庆"),
("重庆", "成都"),
("成都", "西安"),
("西安", "北京"),
]
# 点数据
points_data = [
("北京", 100),
("上海", 150),
("广州", 120),
("深圳", 140),
("成都", 90),
("杭州", 110),
("南京", 80),
("武汉", 85),
("西安", 70),
("重庆", 95),
("青岛", 75),
("长沙", 65),
("厦门", 60),
("哈尔滨", 50),
]
# 创建地理坐标系
geo = (
Geo()
.add_schema(
maptype="china",
itemstyle_opts=opts.ItemStyleOpts(
color="#323c48", border_color="#111"
),
)
.add_coordinate_json(city_coordinates)
.add(
"城市点",
points_data,
type_=ChartType.EFFECT_SCATTER,
symbol_size=8,
effect_opts=opts.EffectOpts(scale=5, period=4),
)
.add(
"城市连线",
lines_data,
type_=ChartType.LINES,
effect_opts=opts.EffectOpts(
symbol=SymbolType.ARROW, symbol_size=6, color="yellow"
),
linestyle_opts=opts.LineStyleOpts(curve=0.2),
)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="中国主要城市交通网络"),
visualmap_opts=opts.VisualMapOpts(
min_=50, max_=150, range_color=["green", "yellow", "red"]
),
)
)
geo.render("china_geo.html")
4.4 3D 地图
from pyecharts.charts import Map3D
from pyecharts import options as opts
from pyecharts.globals import ChartType
# 省份数据
provinces_data = [
("北京", 99),
("上海", 199),
("广东", 299),
("四川", 199),
("山东", 249),
("江苏", 279),
("河北", 165),
("浙江", 259),
("安徽", 155),
("福建", 168),
("江西", 148),
("湖南", 189),
("贵州", 125),
("云南", 145),
("新疆", 80),
("西藏", 50),
]
# 创建3D地图
map3d = (
Map3D()
.add_schema(
itemstyle_opts=opts.ItemStyleOpts(
color="rgb(239,239,255)",
opacity=1,
border_width=0.8,
border_color="rgb(160,161,229)",
),
map3d_label=opts.Map3DLabelOpts(
is_show=False,
formatter="{b}",
text_style=opts.TextStyleOpts(
color="#000", font_size=16, background_color="rgba(0,0,0,0)"
),
),
emphasis_label_opts=opts.LabelOpts(is_show=True),
light_opts=opts.Map3DLightOpts(
main_color="#fff",
main_intensity=1.2,
is_main_shadow=False,
main_alpha=55,
main_beta=10,
ambient_intensity=0.3,
),
)
.add(
"GDP指数",
provinces_data,
maptype="china",
bar_size_max=200,
is_map_symbol_show=True,
type_=ChartType.BAR3D,
)
.set_global_opts(
title_opts=opts.TitleOpts(title="中国3D地图"),
visualmap_opts=opts.VisualMapOpts(
min_=50, max_=300, range_color=["#313695", "#4575b4", "#74add1",
"#abd9e9", "#e0f3f8", "#fee090"]
),
)
)
map3d.render("china_map3d.html")
五、中国传统特色图表
5.1 中国风主题定制
from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType
# 准备数据
x_data = ["茶", "酒", "玉", "瓷", "丝", "扇", "琴", "棋", "书", "画"]
y_data = [35, 28, 24, 42, 18, 15, 12, 22, 30, 25]
# 创建中国风主题的柱状图
bar = (
Bar(init_opts=opts.InitOpts(theme=ThemeType.ROMA)) # 使用罗马主题,类似中国风
.add_xaxis(x_data)
.add_yaxis("文化指数", y_data)
.set_global_opts(
title_opts=opts.TitleOpts(
title="中国传统文化元素指数",
subtitle="非物质文化遗产分析",
pos_le