Python+pyecharts 复刻 B 站爆款动态人口排行榜|1960-2024 世界各国人口动态轮播图 一、前言刷 B 站经常看到各类动态排名轮播柱状图Bar Chart Race人口、GDP 历年变迁动态排行视频播放量动辄几十万。本文基于Pandaspyecharts完整复刻 B 站同款深色风动态人口排行数据集覆盖1960–2024 全球各国人口从原始脏数据清洗→数据重塑→单图测试→全量时间线轮播→B 站风格精细化美化全流程落地生成可交互 HTML 动态排行悬停查看人口、自动轮播、手动切换年份全部实现新手可一键复现全代码。项目最终效果深色暗黑 B 站主题背景柱子随机循环渐变彩色 圆角样式每年自动按人口降序取 Top20人口越多国家排在图表最上方时间轴自动 600ms 切换年份、循环播放支持暂停 / 拖拽切换年份鼠标悬浮单个国家弹窗展示国家名称 精准人口数值导出 HTML 文件浏览器直接打开无需额外部署环境。二、技术栈与环境准备1. 依赖库安装打开 cmd 执行 pip 安装依赖bashpip install pandas pyecharts2. 技术选型说明表格工具用途Pandas原始数据读取、黑名单过滤清洗、宽表转长表、类型转换、空值剔除pyechartsBar 横向柱状图绘制、Timeline 时间线实现逐年轮播、图表样式配置JsCodeJS 自定义动态柱子配色实现不同排名柱子自动换色CDN 替换替换 echarts 国内 CDN解决 HTML 打开空白、资源加载失败问题三、项目整体开发流程整体分四大阶段数据加载探查→黑名单精准清洗→数据格式重塑→可视化分步开发单图→基础轮播→B 站美化完整版四、步骤 1数据导入与全局配置解决国内 HTML 空白坑4.1 全局导包 替换 CDN关键国内必写很多同学生成 HTML 打开空白根源是 pyecharts 默认海外 CDN 无法访问提前替换 jsdelivr 国内镜像python# 1.导入核心工具 import pandas as pd from pyecharts.charts import Bar, Timeline from pyecharts import options as opts from pyecharts.globals import ThemeType, CurrentConfig from pyecharts.commons.utils import JsCode # 修复CDN解决国内网络HTML空白必加配置 CurrentConfig.ONLINE_HOST https://cdn.jsdelivr.net/npm/echarts5.4.3/dist/4.2 读取人口数据集数据集世界人口数据-中文版(1960-2024).csv编码 gbk 避免中文乱码python# 读取中文版人口数据集 df pd.read_csv(./data/世界人口数据-中文版(1960-2024).csv,encodinggbk) # 预览前5行 df.head()4.3 原始数据探查原始数据266 行、70 列4 列基础属性国家名、国家编码、指标名、指标编码剩余 66 列为 1960–2025 年份人口列2025 年全为空值 NaN有效统计区间1960~2024脏数据问题包含全球、各大洲、收入分组、非主权地区港澳台、海外领地汇总数据不能参与国家排行需要黑名单过滤。五、步骤 2核心数据清洗项目重难点黑名单剔除无效数据5.1 定义黑名单剔除非主权 / 汇总数据黑名单包含全球 / 大洲汇总、收入等级分类、世界银行分组、非主权领地 / 海外行政区最终筛选出 195 个合法主权国家python#黑名单:剔除大洲、收入等级、发展区域汇总、非主权地区 black_list [ # 全球 大洲汇总 世界, 北美, 东亚与太平洋地区, 欧洲与中亚地区, 东亚与太平洋地区(不包括高收入), 欧洲与中亚地区(不包括高收入), 拉丁美洲与加勒比海地区, 拉丁美洲与加勒比海地区(不包括高收入), 中东北非阿富汗与巴基斯坦, 中东与北非地区(不包括高收入), 撒哈拉以南非洲地区, 撒哈拉以南非洲地区(不包括高收入), 南亚, 小国, 加勒比小国, 太平洋岛国, 其他小国, 未分类国家, 阿拉伯联盟国家, 欧洲联盟, 欧洲货币联盟, 经合组织成员, 重债穷国 (HIPC), 脆弱和受衝突影響的情況下, # 收入等级 高收入国家, 低收入国家, 中等收入国家, 中高等收入国家, 中低等收入国家, 中低收入国家, #人口红利阶段 早人口紅利, 後期人口紅利, 預人口紅利, 人口紅利之後, #发展水平分类 最不发达国家:联合国分类, # 世界银行分组 IBRD与IDA, 只有IBRD, 只有IDA, IDA總, IDA混合, 东亚与太平洋地区 (IBRD与IDA), 欧洲与中亚地区 (IBRD与IDA), 拉丁美洲与加勒比海地区 (IBRD与IDA), 中东与北非地区 (IBRD与IDA), 南亚 (IBRD与IDA), 撒哈拉以南非洲地区 (IBRD与IDA), # 地区/领地/非主权地区 阿鲁巴, 美属萨摩亚, 百慕大, 库拉索, 开曼群岛, 海峡群岛, 法罗群岛, 直布罗陀, 格陵兰, 关岛, 中国香港特别行政区, 中国澳门特别行政区, 圣马丁(法属), 圣马丁(荷属), 北马里亚纳群岛, 新喀里多尼亚, 波多黎各, 约旦河西岸和加沙, 法属波利尼西亚, 特克斯科斯群岛, 英屬維爾京群島, 美属维京群岛, 科索沃 ] #反向过滤不在黑名单的数据保留 df df[~df[Country Name].isin(black_list)].reset_index(dropTrue) print(过滤后剩余主权国家数量,df[Country Name].nunique())5.2 宽表转长表melt 重塑数据格式原始是宽格式一行国家、多列年份绘图需要长格式一行 某国某一年人口使用pd.melt拆分行python#筛选属性列固定字段和年份列纯数字列 attr_cols [Country Name,Country Code,Indicator Name,Indicator Code] year_cols [col for col in df.columns if col.isdigit()] # melt宽表转为长表 df_long pd.melt( df, id_varsattr_cols, # 不变字段国家信息 value_varsyear_cols, # 需要拆分的所有年份列 var_nameYear, # 拆分后新列年份 value_namePopulation # 拆分后新列人口数值 )5.3 数据类型转换 空值清理python# 只保留绘图需要三列 df_cleandf_long[[Country Name,Year,Population]] #年份转为整数 df_clean[Year]df_clean[Year].astype(int) #人口转为数值类型 df_clean[Population]pd.to_numeric(df_clean[Population]) #删除人口空值剔除2025无效空数据 df_clean.dropna(inplaceTrue) #查看清洗后数据 df_clean.head()清洗后有效数据 12675 条仅保留 195 个主权国家 1960–2024 人口数据。六、步骤 3可视化开发分 3 个版本迭代版本 1单年份静态横向柱状测试1990 年 Top20 人口排行先单年绘图验证逻辑reversal_axis()实现横向柱状深色主题python# 筛选1990年数据 test_dfdf_clean[df_clean[Year]1990] #人口降序取前20 test_dftest_df.sort_values(byPopulation,ascendingFalse).head(20) #绘制单年横向柱状图 bar_test( Bar(init_optsopts.InitOpts(themeThemeType.DARK)) .add_xaxis(test_df[Country Name].tolist()) .add_yaxis(人口,test_df[Population].tolist()) .reversal_axis() #坐标轴反转→横向柱状 .set_global_opts( title_optsopts.TitleOpts(title1990年世界人口排名,pos_leftcenter), legend_optsopts.LegendOpts(is_showFalse), #隐藏图例 ) .set_series_opts(label_optsopts.LabelOpts(positionright)) #数值在柱子右侧 ) bar_test.render_notebook() #jupyter预览 # bar_test.render(1990人口排行.html) #导出html版本 2基础版 TimeLine 全年份自动轮播遍历所有年份逐年生成柱状图加入时间轴实现自动轮播pythonyear_listdf_clean[Year].unique().tolist() #初始化时间线 timeline Timeline(init_optsopts.InitOpts(width1500px,height820px,themeThemeType.DARK,bg_color#0a0a0a)) #循环每一年绘图 for year in year_list: data_dfdf_clean[df_clean[Year]year] #降序取top20再升序排序配合反转坐标轴大数在上 data_dfdata_df.sort_values(byPopulation,ascendingFalse).head(20) data_dfdata_df.sort_values(byPopulation,ascendingTrue) countrydata_df[Country Name].tolist() populationdata_df[Population].tolist() bar( Bar(init_optsopts.InitOpts(themeThemeType.DARK)) .add_xaxis(country) .add_yaxis(人口,population) .reversal_axis() .set_global_opts( title_optsopts.TitleOpts(titlef{year}年世界人口排名,pos_leftcenter), legend_optsopts.LegendOpts(is_showFalse), ) .set_series_opts(label_optsopts.LabelOpts(positionright)) ) timeline.add(bar,str(year)) #设置自动播放、循环切换 timeline.add_schema(is_auto_playTrue,play_interval600,is_loop_playTrue) timeline.render_notebook() # timeline.render(基础版人口轮播.html)排序关键知识点先降序取 Top20再升序 reversal_axis()人口最多的国家会固定在图表最上方符合观看习惯。版本 3B 站高级美化完整版最终成品代码增加JS 动态变色、圆角柱子、自定义时间轴样式、标签格式化对标 B 站视频可视化风格python# 初始化最终时间线画布 timeline_final Timeline(init_optsopts.InitOpts( width1600px, height850px, themeThemeType.DARK, bg_color#080808 #极深黑B站背景 )) # JS代码实现柱子循环随机配色 color_js JsCode( function(params){ let c [#ff4757,#ffa502,#fffa65,#2ed573,#1e90ff,#3742fa,#a55eea,#48dbfb]; return c[params.dataIndex % c.length]; } ) year_listdf_clean[Year].unique().tolist() #循环逐年绘图 for year in year_list: data_dfdf_clean[df_clean[Year]year] data_dfdata_df.sort_values(byPopulation,ascendingFalse).head(20) data_dfdata_df.sort_values(byPopulation,ascendingTrue) countrydata_df[Country Name].tolist() populationdata_df[Population].tolist() bar( Bar(init_optsopts.InitOpts(themeThemeType.DARK)) .add_xaxis(country) .add_yaxis(人口,population, #圆角、透明度、动态颜色 itemstyle_optsopts.ItemStyleOpts(colorcolor_js,opacity0.85,border_radius7), #标签格式化数字人 label_optsopts.LabelOpts(positionright,formatter{c}人,font_size11) ) .reversal_axis() .set_global_opts( title_optsopts.TitleOpts(titlef{year}年世界人口排名,pos_leftcenter), legend_optsopts.LegendOpts(is_showFalse), ) ) timeline_final.add(bar,str(year)) #精细化配置时间轴样式蓝色进度条、白色节点、加粗年份文字 timeline_final.add_schema( is_auto_playTrue, is_loop_playTrue, play_interval600, #600ms切换一年 is_timeline_showTrue, pos_leftcenter, width95%, label_optsopts.LabelOpts(color#ffffff, font_size11,font_weightbold), linestyle_optsopts.LineStyleOpts(color#00a1ff, width4), itemstyle_optsopts.ItemStyleOpts(color#00a1ff,border_color#ffffff, border_width2), ) #导出最终HTML文件 timeline_final.render(B站同款人口动态排行.html) timeline_final.render_notebook()七、项目成果总结✅数据层面剔除全球汇总、地区、非主权地区脏数据精准保留 195 个主权国家 1960–2024 人口数据 ✅交互层面自动轮播、暂停播放、手动拖拽年份、悬浮查看人口全部实现 ✅视觉层面深色 B 站暗黑风格、圆角渐变彩色柱子、精细化时间轴对标 B 站数据视频 ✅落地成果生成独立 HTML 文件脱离 Python 环境任意浏览器打开即可运行。八、后续优化拓展方向国旗优化X 轴国家名称前嵌入各国国旗 Base64 图标视觉效果更强多指标切换增加下拉框一键切换人口总数 / 人口增长率 / GDP 排行性能优化百万级大数据提前预计算各年份 Top20 缓存减少前端渲染压力导出视频通过 selenium 自动截图 HTML 轮播拼接生成 MP4 排行视频。九、踩坑总结避坑指南HTML 空白必须替换CurrentConfig.ONLINE_HOST国内 CDN否则 echarts 资源加载失败排序颠倒排行榜必须「降序取 TOP→升序 反转坐标轴」两步否则排名倒置中文乱码csv 读取指定encodinggbk国内中文版数据集通用空值报错原始数据 2025 全为空dropna()提前剔除无效数据。