暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

2024 最火的数据可视化技巧:用 pyecharts 做中国统计地图,颜值吊打原生图表

追梦IT人 2025-08-08
119

一、什么是 pyecharts?

pyecharts 是一款基于 Python 的强大可视化库,它无缝对接 ECharts,让开发者无需深入学习 JavaScript,就能用 Python 代码生成交互式图表 —— 从折线图、柱状图到地理地图、3D 模型,覆盖近百种可视化场景。尤其在地理数据展示上,pyecharts 的地图模块支持中国省市县多级区划,能轻松实现数据与地理区域的绑定,是统计分析、政务汇报、学术研究中展示地域数据的热门工具。无论是人口分布、GDP 差异还是疫情数据,都能通过它转化为直观的地图可视化成果。

二、pyecharts 的 “先天不足”:颜值与定制化的短板

尽管功能强大,pyecharts 的 “原生状态” 却常被诟病。一方面,默认样式过于朴素:地图底色单调、省份边界模糊、颜色渐变生硬,与专业设计工具产出的可视化作品相比,显得简陋粗糙;另一方面,定制化门槛暗藏玄机 —— 虽然提供了大量配置项,但参数分散、逻辑复杂,新手很容易陷入 “改了这处乱了那处” 的困境。比如想调整地图悬停效果,可能要同时修改itemstyle、tooltip、emphasis等多个配置,稍不注意就会导致图表错乱。这些问题让不少人觉得:“pyecharts 能画出来,但画不漂亮。”

三、调参,才是解锁 pyecharts 潜力的关键

事实上,pyecharts 的 “颜值天花板” 远未被默认配置限制。它的核心魅力恰恰在于高度可定制的参数体系 —— 就像给相机调光圈、快门能拍出不同风格的照片,修改 pyecharts 的配置项,能让同一份数据呈现出完全不同的视觉效果。比如通过bg_color更换地图背景为深邃星空蓝,用range_color设置渐变色带增强层次感,调整label_opts让省份名称既清晰又不突兀,再加上emphasis_opts配置悬停时的高亮动画…… 只需十几行参数调整,原本朴素的地图就能蜕变为符合大屏展示、汇报演讲的 “高颜值作品”。所谓 “工欲善其事,必先利其器”,掌握调参技巧,才能让 pyecharts 从 “能用” 变成 “好用、好看”。



如果我们平常用pyecharts实现地图数据可视化,是不是会得到以下的图表,这个图的确可以表达出数据分析的含义,但却没法拿的出手。
想做出精美的媲美大屏风格的地图可视化,需要对pyecharts进行全面剖析,比如对全局配置项、系列配置项,对其里面的各项参数,甚至包括内置的js代码,老规矩,先上代码,再上图,注释都在代码里:
from pyecharts.charts import Map
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode

# 示例数据
province_data = [
    ("广东省"126012510),
    ("山东省"101527453),
    ("河南省"99365519),
    ("四川省"83674866),
    ("江苏省"84748016),
    ("河北省"74610235),
    ("湖南省"66444864),
    ("浙江省"64567588),
    ("安徽省"61027171),
    ("湖北省"57752557),
    ("广西壮族自治区"50126804),
    ("云南省"47209277),
    ("江西省"45188635),
    ("辽宁省"42591407),
    ("福建省"41540086),
    ("陕西省"39528999),
    ("黑龙江省"31850088),
    ("山西省"34915616),
    ("贵州省"38562148),
    ("重庆市"32054159),
    ("吉林省"24073453),
    ("甘肃省"25019831),
    ("内蒙古自治区"24000207),
    ("上海市"24870895),
    ("新疆维吾尔自治区"25890094),
    ("北京市"21893095),
    ("天津市"13866009),
    ("海南省"10081232),
    ("宁夏回族自治区"7202654),
    ("青海省"5923957),
    ("西藏自治区"3648100)
]
gdp_data = [
    ("广东省"124369.67), ("山东省"83095.90), ("河南省"58887.41),
    ("四川省"53850.79), ("江苏省"116364.2), ("河北省"40391.3)
]

# 中国式大屏风格地图
china_map = (
    # InitOpts:初始化配置项
    Map(init_opts=opts.InitOpts(
        chart_id="123",
        bg_color="#001529",  # 深蓝色背景,符合政务大屏风格
        page_title="中国人口分布大屏",
    ))
   .add(
        series_name="人口数量",
        data_pair=province_data,
        maptype="china",
        zoom=1.2,  # 适当缩放,让地图居中显示
        center=[10536],  # 中国地理中心坐标
        itemstyle_opts=opts.ItemStyleOpts(
            area_color="#142957",  # 省份底色
            border_color="#00f2fe",  # 边界颜色,亮青色
            border_width=0.5,
            # opacity=0.5,
        )
    )
    .add(
        series_name="GDP",
        data_pair=gdp_data,
        maptype="china",
        zoom=1.2,  # 适当缩放,让地图居中显示
        center=[10536],  # 中国地理中心坐标
        itemstyle_opts=opts.ItemStyleOpts(
            area_color="#142957",  # 省份底色
            border_color="#00f2fe",  # 边界颜色,亮青色
            border_width=0.5,
            # opacity=0.5,
        )
    )
    # set_series_opts 系列配置项设置
   .set_series_opts(
        # label_opts 标签配置项
        label_opts=opts.LabelOpts(
            is_show=True,  # 是否显示标签
            color="#ffffff",  # 文字颜色
            font_size=8# 文字字体大小
            font_weight="normal"# 文字字体粗细
            font_family="SimHei"# 文字字体系列
        ),
        # emphasis_opts 鼠标悬停效果
        emphasis_opts=opts.ItemStyleOpts(
            area_color="#00f2fe",  # 悬停时省份颜色
            border_color="#ffffff"# 图形描边颜色
            border_width=2# 描边宽度
        )
    )
    # set_global_opts 全局配置项设置
   .set_global_opts(
        # title_opts 标题样式
        title_opts=opts.TitleOpts(
            title="中国各省份人口分布",
            subtitle="数据来源:最新人口普查数据",
            # title_textstyle_opts 主标题设置
            title_textstyle_opts=opts.TextStyleOpts(
                color="#00f2fe",  # 标题颜色
                font_size=36,
                font_weight="bold",
                font_family="SimHei"
            ),
            # subtitle_textstyle_opts 副标题设置
            subtitle_textstyle_opts=opts.TextStyleOpts(
                color="#ffffff",
                font_size=16,
            ),
            pos_top="2%",
            pos_left="center",
        ),
        # visualmap_opts 视觉映射配置
        visualmap_opts=opts.VisualMapOpts(
            is_show=True,
            type_="color",
            min_=3000000,
            max_=130000000,
            range_text=["高""低"],
            range_color=["#00f2fe""#0066b2""#001529"],  # 蓝青色渐变,符合中国风
            textstyle_opts=opts.TextStyleOpts(color="#ffffff", font_size=10),
            pos_right="5%",
            pos_bottom="10%",
            item_width=15,
            item_height=100,
            border_color="#00f2fe",
            border_width=2
        ),
        # legend_opts 图例设置
        legend_opts=opts.LegendOpts(
            is_show=False
        ),
        # tooltip_opts 提示框样式
        tooltip_opts=opts.TooltipOpts(
            trigger="item",
            background_color="rgba(0, 21, 41, 0.9)",
            border_color="#00f2fe",
            border_width=1,
            textstyle_opts=opts.TextStyleOpts(color="#ffffff", font_size=16),
            formatter=JsCode("""
                function(params) {
                    return `<div style="padding:10px;">
                        <div style="font-size:12px;font-weight:bold;">${params.name}</div>
                        <div style="font-size:12px;margin-top:5px;">人口数量:${params.value.toLocaleString()}人</div>
                    </div>`;
                }
            """
)
        )
    )    # 简化JS交互

)

china_map.render("china_population_big_screen.html")

我们可以看一下本次地图可视化呈现的效果了。

对于多指标切换怎么办?原本想按照正常图表中实现指标切换,但对pyecharts的JS代码调了一整天,这个VisualMapOpts:视觉映射配置项一直不能跟随指标上下限进行实时调整,无奈放弃了,只能换一个思路,做成tab方式,其实这个案例还可以继续优化其组件,让其更像大屏风格。

from pyecharts.charts import Map, Tab
from pyecharts import options as opts

# 示例数据
data_gdp = [("广东省", 10000), ("四川省", 20000), ("黑龙江省", 25000)]
data_population = [("广东省", 8000), ("四川省", 2300), ("黑龙江省", 2500)]

# 创建地图图表
map_gdp = Map(init_opts=opts.InitOpts(
        chart_id="gdp",
        bg_color="#001529",  # 深蓝色背景,符合政务大屏风格
        width = "900px",
        height = "500px",
        page_title="中国GDP分布大屏",
    ))
map_gdp.add("GDP", data_gdp, "china")
map_gdp.set_global_opts(
    title_opts=opts.TitleOpts(title="中国各省份GDP"),
    visualmap_opts=opts.VisualMapOpts(max_=30000)
)

map_population = Map(init_opts=opts.InitOpts(
        chart_id="population",
        bg_color="#001529",  # 深蓝色背景,符合政务大屏风格
        width = "900px",
        height = "500px",
        page_title="中国人口分布大屏",
    ))
map_population.add("Population", data_population, "china")
map_population.set_global_opts(
    title_opts=opts.TitleOpts(title="中国各省份人口"),
    visualmap_opts=opts.VisualMapOpts(max_=8000)
)

# 使用 Tab 创建切换界面
tab = Tab()
tab.add(map_gdp, "GDP")
tab.add(map_population, "Population")

# 渲染图表到 HTML 文件
tab.render("map_tabs.html")

tab切换的地图指标


关于随时间序列变化的数据,在pyecharts的示例中是有的,不过我们不需要那么复杂的,在此做了精简,完全可以参照之前的方式对地图再进行美化,这里就不再赘述了。


import pyecharts.options as opts
from pyecharts.globals import ThemeType
from pyecharts.commons.utils import JsCode
from pyecharts.charts import Timeline, Grid, Bar, Map, Pie

"""
Gallery 使用 pyecharts 1.0.0
参考地址: https://gallery.echartsjs.com/editor.html?c=xSkGI6zLmb

目前无法实现的功能:

1、
"""


data = [
    {
        "time"1980,
        "data": [
            {"name""台湾省""value": [633.7612.28"台湾省"]},
            {"name""香港特别行政区""value": [432.478.38"香港特别行政区"]},
            {"name""江苏省""value": [319.86.2"江苏省"]},
            {"name""上海市""value": [311.896.05"上海市"]},
            {"name""山东省""value": [292.135.66"山东省"]},
            {"name""辽宁省""value": [2815.45"辽宁省"]},
            {"name""广东省""value": [249.654.84"广东省"]},
            {"name""四川省""value": [229.314.44"四川省"]},
            {"name""河南省""value": [229.164.44"河南省"]},
            {"name""黑龙江省""value": [2214.28"黑龙江省"]},
        ],
    },
    {
        "time"2000,
        "data": [
            {"name""台湾省""value": [27435.1519.47"台湾省"]},
            {"name""香港特别行政区""value": [14201.5910.08"香港特别行政区"]},
            {"name""广东省""value": [10741.257.62"广东省"]},
            {"name""江苏省""value": [8553.696.07"江苏省"]},
            {"name""山东省""value": [8337.475.92"山东省"]},
            {"name""浙江省""value": [6141.034.36"浙江省"]},
            {"name""河南省""value": [5052.993.59"河南省"]},
            {"name""河北省""value": [5043.963.58"河北省"]},
            {"name""上海市""value": [4771.173.39"上海市"]},
            {"name""辽宁省""value": [4669.13.31"辽宁省"]},
        ],
    },
    {
        "time"2005,
        "data": [
            {"name""台湾省""value": [30792.8912.52"台湾省"]},
            {"name""广东省""value": [22527.379.16"广东省"]},
            {"name""江苏省""value": [18598.697.56"江苏省"]},
            {"name""山东省""value": [18366.877.47"山东省"]},
            {"name""香港特别行政区""value": [14869.686.05"香港特别行政区"]},
            {"name""浙江省""value": [13417.685.46"浙江省"]},
            {"name""河南省""value": [10587.424.3"河南省"]},
            {"name""河北省""value": [10043.424.08"河北省"]},
            {"name""上海市""value": [9247.663.76"上海市"]},
            {"name""辽宁省""value": [8047.33.27"辽宁省"]},
        ],
    },
    {
        "time"2010,
        "data": [
            {"name""广东省""value": [46036.259.49"广东省"]},
            {"name""江苏省""value": [41425.488.54"江苏省"]},
            {"name""山东省""value": [39169.928.08"山东省"]},
            {"name""台湾省""value": [30205.646.23"台湾省"]},
            {"name""浙江省""value": [27747.655.72"浙江省"]},
            {"name""河南省""value": [23092.364.76"河南省"]},
            {"name""河北省""value": [20394.264.21"河北省"]},
            {"name""辽宁省""value": [18457.33.81"辽宁省"]},
            {"name""四川省""value": [17185.483.54"四川省"]},
            {"name""上海市""value": [17165.983.54"上海市"]},
        ],
    },
    {
        "time"2015,
        "data": [
            {"name""广东省""value": [72812.559.35"广东省"]},
            {"name""江苏省""value": [70116.389"江苏省"]},
            {"name""山东省""value": [63002.38.09"山东省"]},
            {"name""浙江省""value": [428865.51"浙江省"]},
            {"name""河南省""value": [37010.254.75"河南省"]},
            {"name""台湾省""value": [32604.524.19"台湾省"]},
            {"name""四川省""value": [30103.13.87"四川省"]},
            {"name""河北省""value": [29806.13.83"河北省"]},
            {"name""湖北省""value": [29550.193.8"湖北省"]},
            {"name""湖南省""value": [29047.23.73"湖南省"]},
        ],
    },
]


def get_year_chart(year: int):
    map_data = [
        [[x["name"], x["value"]] for x in d["data"]] for d in data if d["time"] == year
    ][0]
    print(year,'\n',map_data)
    min_data, max_data = (
        min([d[1][0for d in map_data]),
        max([d[1][0for d in map_data]),
    )
    map_chart = (
        Map()
        .add(
            series_name="",
            data_pair=map_data,
            label_opts=opts.LabelOpts(is_show=False),
            is_map_symbol_show=False,
            itemstyle_opts={
                "normal": {"areaColor""#323c48""borderColor""#404a59"},
                "emphasis": {
                    "label": {"show": Timeline},
                    "areaColor""rgba(255,255,255, 0.5)",
                },
            },
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(
                title="1980年以来中国各省GDP排名变化情况",
                subtitle="GDP单位:亿元",
                pos_left="center",
                pos_top="top",
                title_textstyle_opts=opts.TextStyleOpts(
                    font_size=25, color="rgba(255,255,255, 0.9)"
                ),
            ),
            tooltip_opts=opts.TooltipOpts(
                is_show=True,
                formatter=JsCode(
                    """function(params) {
                    if ('value' in params.data) {
                        return params.data.value[2] + ': ' + params.data.value[0];
                    }
                }"""

                ),
            ),
            visualmap_opts=opts.VisualMapOpts(
                is_calculable=True,
                dimension=0,
                pos_left="10",
                pos_top="center",
                range_text=["High""Low"],
                range_color=["lightskyblue""yellow""orangered"],
                textstyle_opts=opts.TextStyleOpts(color="#ddd"),
                min_=min_data,
                max_=max_data,
            ),
        )
    )
    return map_chart

# Draw Timeline
time_list = [19802000200520102015]
timeline = Timeline(
    init_opts=opts.InitOpts(width="1200px", height="800px", theme=ThemeType.DARK)
)
for y in time_list:
    g = get_year_chart(year=y)
    timeline.add(g, time_point=str(y))

timeline.add_schema(
    orient="vertical",
    is_auto_play=True,
    is_inverse=True,
    play_interval=5000,
    pos_left="null",
    pos_right="5",
    pos_top="20",
    pos_bottom="20",
    width="50",
    label_opts=opts.LabelOpts(is_show=True, color="#fff"),
)

timeline.render("china_gdp_from_1980.html")

基于timeline的地图指标变化。

最后欢迎关注公众号:python与大数据分析


文章转载自追梦IT人,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论