当我们需要快速呈现疫情数据的空间分布特征时,一个直观的可视化地图往往胜过千言万语的描述。Pyecharts作为Python生态中强大的可视化工具,其最新1.6.2版本在地图渲染和交互体验上有了显著提升。本文将带您从零开始,用不到50行代码构建专业的疫情热力图,并深入探讨那些官方文档未曾明说的实用技巧。
在开始之前,确保您的Python环境已安装Pyecharts 1.6.2版本。这个版本修复了之前地图组件中的多个边界渲染问题,特别适合精确的地理数据可视化:
bash复制pip install pyecharts==1.6.2
pip install pandas # 用于数据处理
疫情数据通常可以从公开数据平台获取,这里我们模拟一份结构化数据。实际应用中,您可能会从API接口或数据库读取真实数据:
python复制import pandas as pd
data = {
"城市": ["北京市", "上海市", "广州市", "深圳市", "武汉市", "成都市"],
"新增病例": [45, 32, 28, 19, 15, 22],
"累计病例": [1205, 980, 650, 420, 50320, 850]
}
df = pd.DataFrame(data)
提示:Pyecharts对中文地理名称的支持在1.6.2版本有明显改善,但仍建议检查城市名是否与标准名称一致,避免渲染异常。
让我们从最简单的省级地图开始。以下代码展示了如何创建一个展示各省累计病例的基础热力图:
python复制from pyecharts import options as opts
from pyecharts.charts import Map
provinces = ["湖北省", "广东省", "浙江省", "河南省", "湖南省"]
cases = [50320, 3200, 2800, 2500, 1800]
map_chart = (
Map()
.add("累计病例", [list(z) for z in zip(provinces, cases)], "china")
.set_global_opts(
title_opts=opts.TitleOpts(title="全国疫情分布图"),
visualmap_opts=opts.VisualMapOpts(max_=50000)
)
)
map_chart.render("national_cases.html")
这段代码会生成一个可交互的HTML文件,其中:
add()方法绑定数据到地图set_global_opts()配置标题和视觉映射参数render()输出最终可视化结果对于疫情数据,我们通常需要更精细的分段显示。Pyecharts的is_piecewise参数可以实现这个需求:
python复制visualmap_opts=opts.VisualMapOpts(
max_=50000,
is_piecewise=True,
pieces=[
{"min": 0, "max": 99, "label": "0-99例", "color": "#FFFACD"},
{"min": 100, "max": 999, "label": "100-999例", "color": "#FFA07A"},
{"min": 1000, "max": 9999, "label": "1000-9999例", "color": "#CD5C5C"},
{"min": 10000, "label": "10000例以上", "color": "#8B0000"}
]
)
当需要展示城市级别的数据时,需要指定具体的地图类型。以下是展示湖北省内城市分布的示例:
python复制hubei_cities = ["武汉市", "孝感市", "黄冈市", "荆州市", "宜昌市"]
city_cases = [50320, 3482, 2904, 1576, 926]
city_map = (
Map()
.add("确诊病例", [list(z) for z in zip(hubei_cities, city_cases)], "湖北")
.set_global_opts(
title_opts=opts.TitleOpts(title="湖北省疫情分布"),
visualmap_opts=opts.VisualMapOpts(max_=50000)
)
)
注意:Pyecharts内置支持多种地图类型,包括"china"、"world"以及各省名称。使用前需确保已通过
pip install echarts-countries-pypkg echarts-china-provinces-pypkg echarts-china-cities-pypkg安装相应地图包。
要展示疫情随时间的变化,可以使用Timeline组件:
python复制from pyecharts.charts import Timeline, Map
from pyecharts.globals import CurrentConfig
CurrentConfig.ONLINE_HOST = "https://cdn.jsdelivr.net/npm/echarts@4.8.0/dist/"
timeline = Timeline()
for month in ["1月", "2月", "3月"]:
# 模拟不同月份数据
cases = [x * (1 + i*0.5) for i, x in enumerate([50320, 3200, 2800])]
map_chart = (
Map()
.add(month, [list(z) for z in zip(provinces, cases)], "china")
.set_global_opts(visualmap_opts=opts.VisualMapOpts(max_=100000))
)
timeline.add(map_chart, month)
timeline.render("timeline.html")
通过定制tooltip可以显示更丰富的信息:
python复制.set_series_opts(
label_opts=opts.LabelOpts(is_show=False),
tooltip_opts=opts.TooltipOpts(
formatter="""
function(params){
return params.name + '<br/>' +
'新增:' + params.data.value[1] + '<br/>' +
'累计:' + params.data.value[2];
}
"""
)
)
当处理大规模地理数据时,可能会遇到性能瓶颈。以下是几个优化建议:
python复制.set_series_opts(animation_opts=opts.AnimationOpts(animation=False))
python复制CurrentConfig.ONLINE_HOST = "https://cdn.jsdelivr.net/npm/echarts@4.8.0/dist/"
常见问题解决方案:
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| 地图显示空白 | 未安装对应地图包 | pip安装相应pypkg包 |
| 中文显示乱码 | 字体配置问题 | 设置全局字体选项 |
| 悬停无响应 | 数据格式错误 | 检查数据是否为[[name, value]]格式 |
一个完整的市级疫情地图示例,整合了上述所有优化技巧:
python复制def create_city_map():
map_chart = (
Map(init_opts=opts.InitOpts(width="1200px", height="800px"))
.add(
series_name="疫情数据",
data_pair=[list(z) for z in zip(hubei_cities, city_cases)],
maptype="湖北",
is_map_symbol_show=False,
label_opts=opts.LabelOpts(
font_size=12,
color="#333",
formatter="{b}: {c}"
)
)
.set_global_opts(
title_opts=opts.TitleOpts(
title="湖北省疫情实时分布",
subtitle="数据更新至{}".format(pd.Timestamp.now().strftime("%Y-%m-%d")),
pos_left="center"
),
visualmap_opts=opts.VisualMapOpts(
max_=50000,
is_piecewise=True,
pieces=pieces,
pos_left="10%"
),
tooltip_opts=opts.TooltipOpts(
trigger="item",
formatter="{b}<br/>累计病例: {c}"
)
)
)
return map_chart
在实际项目中,我发现将地图与折线图结合展示时间趋势特别有效。Pyecharts的Page组件可以轻松实现这种组合视图,让分析维度更加立体。