数据分析实战:Python+pyecharts复刻B站风世界人口动态排序轮播图(Race Bar)
项目概述
1.1 项目背景
动态排序轮播图(Race Chart / Bar Chart Race)是数据可视化热门图表,在B站数据分析类视频中出镜率极高。本项目依托Python数据分析与可视化技术,基于世界人口数据集,复刻1960–2024年全球各国总人口动态排名轮播图,直观展示近65年全球人口格局变迁。
1.2 项目目标
1. 数据清洗:剔除大洲、收入分组、地区汇总等非主权国家数据,最终仅保留195个有效主权国家数据;
2. 动态图表:年份自动轮播切换,每年按人口数值降序排行,悬浮弹窗展示精准人口数,支持暂停/手动跳转年份;
3. 视觉优化:深色主题背景、渐变配色、圆角数值标签,对标B站专业可视化成品风格。
二、技术栈与运行环境
- 数据处理:Python3.x + Pandas(数据读取、空值清洗、宽表转长表重塑)
- 可视化引擎:pyecharts(Bar柱状图 + Timeline时间轴实现轮播)
- 环境适配:JsCode自定义前端动画、CDN镜像配置,解决国内HTML白屏加载问题
python
# 导入核心依赖包
import pandas as pd
from pyecharts.charts import Bar, Timeline
from pyecharts.globals import ThemeType
from pyecharts.commons.utils import JsCode
# 配置国内CDN,解决网页资源加载空白(国内环境必加)
from pyecharts.options import opts
currentConfig = opts.InitOpts()
currentConfig.ONLINE_HOST = "https://cdn.jsdelivr.net/npm/echarts/dist/"
三、数据获取与探查
3.1 数据加载
数据源: 世界人口数据-中文版(1960-2024).csv ,文件含中文字符,读取时编码指定 gbk 。
python
# 读取人口数据集
df = pd.read_csv("./data/世界人口数据-中文版.csv",encoding="gbk")
df.head()
字段预览: Country Name(国家名)、Country Code(国家代码)、Indicator Name、Indicator Code、1960~2024逐年人口列 。
3.2 数据结构探查
执行 df.info() 查看数据集基础信息:
- 原始数据:266行、70列;
- 固定属性列4列:国家名称、国家编码、指标名称、指标编码;
- 时间序列列66列:1960~2025,2025全字段为空值NaN,有效数据区间1960–2024;
- 存在汇总行:各大洲、经济分组(高收入/低收入)等非国家数据,是后续清洗重点。
四、数据清洗与预处理(项目核心)
原始数据为宽表格式:一行=一个统计对象,年份横向铺开为多列,混杂大量汇总类无效数据,无法直接绘图,分步处理如下。
4.1 拆分属性列与年份列
区分固定字段(国家信息)、年份数字字段,筛选出1960~2024所有年份字段:
python
# 固定属性字段
attr_cols = ["Country Name","Country Code","Indicator Name","Indicator Code"]
# 提取所有年份列
year_cols = [str(i) for i in range(1960,2025)]
4.2 剔除无效汇总数据(关键清洗步骤)
1. 删除国家名为空行: df = df.dropna(subset=["Country Name"]) ,剔除大洲汇总空名称行;
2. 黑名单过滤:自定义黑名单列表,过滤全球、各大洲、经济收入分组、港澳台地区等非主权国家条目:
python
# 黑名单:大洲、地区、经济分组、特殊行政区汇总名称
black_list = ["世界","东亚与太平洋地区","高收入经济体","欧盟","中国香港","中国澳门","撒哈拉以南非洲","北美","中东北非"]
# 反向过滤,只保留不在黑名单内的数据
df = df[~df["Country Name"].isin(black_list)]
# 过滤后剩余195个主权国家数据
4.3 宽表转长表(melt数据重塑)
Pandas的 melt 实现宽表转长表,将横向年份转为纵向 Year 字段、人口数值转为 Population 字段,适配绘图数据格式:
python
df_long = df.melt(
id_vars=attr_cols, # 固定不变字段
value_vars=year_cols,# 需要拆分行的年份列
var_name="Year", # 拆分后新列:年份
value_name="Population"#拆分后新列:人口
)
df_long.head()
转换后数据结构: 国家名-年份-人口 标准三列式。
4.4 数据类型转换与空值处理
1. Year 字段转为int整数型;
2. Population 人口转为数值型,填充/剔除空值;
3. 筛选最终有效字段: ["Country Name","Year","Population"] 。
python
# 年份转整型
df_long["Year"] = df_long["Year"].astype(int)
# 人口转为数字格式,无法转换的内容设为空
df_long["Population"] = pd.to_numeric(df_long["Population"],errors="coerce")
# 删除人口空值行
df_clean = df_long.dropna(subset=["Population"])
五、Pyecharts动态轮播图代码实现
5.1 循环年份生成单年柱状图
python
# 初始化时间轴,横向排布
tl = Timeline(init_opts=opts.InitOpts(theme=ThemeType.MACARONS))
# 按年份循环构建柱状图
for year in range(1960,2025):
# 筛选当年数据、按人口降序、取Top15国家排行
data_year = df_clean[df_clean["Year"]==year].sort_values("Population",ascending=False).head(15)
bar = (
Bar(init_opts=opts.InitOpts(width="1200px",height="700px"))
.add_xaxis(data_year["Country Name"].tolist())
.add_yaxis("总人口(人)",data_year["Population"].tolist(),bar_width="60%")
.reversal_axis() # 坐标轴倒置,人口多的在顶部
.set_global_opts(
title_opts=opts.TitleOpts(title=f"{year}年全球各国人口TOP15排行",subtitle="动态轮播人口变化"),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(is_show=False)),
tooltip_opts=opts.TooltipOpts(trigger="axis",formatter="国家:{b}<br>人口:{c:,}")
)
)
tl.add(bar,str(year))
# 生成html文件
tl.render("世界人口动态排行轮播图.html")
5.2 进阶B站风格优化(可选)
1. 更换深色主题 ThemeType.DARK 实现黑底配色;
2. 通过 JsCode 自定义柱状圆角、渐变填充色;
3. 配置Timeline自动播放、播放速度、暂停按钮。
python
# 深色主题初始化
tl = Timeline(init_opts=opts.InitOpts(theme=ThemeType.DARK))
# 时间轴自动播放配置
tl.add_schema(
play_interval=600, # 单年份停留600ms
is_auto_play=True,
is_loop_play=True
)
六、项目成果总结
1. 数据层面:原始266条数据清洗为195个国家65年连续人口数据,剔除汇总、地区、行政区无效数据;
2. 可视化成果:生成可交互HTML轮播图,打开即可自动逐年播放各国人口排名变化,悬浮查看详细人口;
3. 拓展方向:可新增大洲筛选、人口增速排行、近10年人口增速变化子图表。
七、使用说明
1. 新建 data 文件夹,放入人口CSV数据源;
2. 安装依赖: pip install pandas pyecharts ;
3. 运行代码,同目录生成 世界人口动态排行轮播图.html ,浏览器打开即可查看动态效果。
源码与数据集可私信获取,需要数据集文件的小伙伴评论区留言
更多推荐



所有评论(0)