news 2026/6/15 4:43:17

世界人口排序轮播图

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
世界人口排序轮播图

数据分析项目报告:B站风格世界人口动态排序轮播图

1. 项目概述

1.1 项目背景

动态排序轮播图(Bar Chart Race)是数据可视化领域的经典形式,尤其在 B 站等视频平台广受欢迎。
本项目旨在通过 Python 数据分析与可视化技术,完整复刻高质量的世界人口年度动态排序轮播图,展
示 1960 年至 2024 年间世界各国人口总数的历史变迁。

1.2 项目目标

数据纯净:完整剔除大洲、收入组、地区汇总等非国家数据,仅保留 195 个真实主权国家。
动态展示:图表自动按年份轮播,每年严格按人口总数降序排列(人口越多的国家越靠图表上
方)。
全交互体验:支持悬浮显示具体人口数值、暂停/播放控制、手动切换年份。
商业级美化:采用深色背景、动态配色、圆角数值标签及丝滑轮播节奏,达到 B 站专业级可视化
标准。

2. 技术栈与运行环境

编程语言:Python 3.x
数据处理: pandas (用于数据读取、清洗、宽长表转换)
数据可视化: pyecharts (Bar 柱状图, Timeline 时间线轮播组件)
前端配置: JsCode (用于实现动态颜色映射), CDN 镜像配置 (解决国内网络加载空白问题)\

# 1. 导入核心工具importpandasaspd# 数据处理库frompyecharts.chartsimportBar,Timeline# 柱状图、时间线轮播组件frompyechartsimportoptionsasopts# 配置项工具frompyecharts.globalsimportThemeType,CurrentConfig# 内置主题、CDN配置frompyecharts.commons.utilsimportJsCode# 动态颜色JS工具# 修复CDN,解决HTML空白问题(国内网络必加)CurrentConfig.ONLINE_HOST="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/"

3. 数据获取与探查 (阶段 1)

3.1 数据加载

项目读取本地 CSV 文件 世界人口数据-中文版(1960-2024).csv ,由于包含中文字符,指定编码为
gbk 。

# 2. 读取中文版人口数据集df=pd.read_csv('E:\jupeyter code\VS code\data\世界人口数据-中文版(1960-2024).csv',encoding='gbk')df.head()
Country NameCountry CodeIndicator NameIndicator Code196019611962196319641965...2016201720182019202020212022202320242025
0阿鲁巴ABW人口,总数SP.POP.TOTL54922.055578.056320.057002.057619.058190.0...108727.0108735.0108908.0109203.0108587.0107700.0107310.0107359.0107995.0NaN
1NaNAFE人口,总数SP.POP.TOTL130075728.0133534923.0137171659.0140945536.0144904094.0149033472.0...623369401.0640058741.0657801085.0675950189.0694446100.0713090928.0731821393.0750491370.0769280888.0NaN
2阿富汗AFG人口,总数SP.POP.TOTL9035043.09214083.09404406.09604487.09814318.010036008.0...34700612.035688935.036743039.037856121.039068979.040000412.040578842.041454761.042647492.0NaN
3NaNAFW人口,总数SP.POP.TOTL97630925.099706674.0101854756.0104089175.0106388440.0108772632.0...429454743.0440882906.0452195915.0463365429.0474569351.0485920997.0497387180.0509398589.0521764076.0NaN
4安哥拉AGO人口,总数SP.POP.TOTL5231654.05301583.05354310.05408320.05464187.05521981.0...29183070.030234839.031297155.032375632.033451132.034532429.035635029.036749906.037885849.0NaN

5 rows × 70 columns

3.2 数据结构探查

通过 df.info() 探查,数据集基础结构如下:

样本量:266 行(包含国家及各类汇总区域)。
特征量:70 列。
属性列 (4列): Country Name (国家名称), Country Code (国家代码), Indicator Name
(指标名称), Indicator Code (指标代码)。
时间序列列 (66列): 1960 至 2025 年的数值列。其中 2025 年数据全为 NaN (缺失),有效数
据区间为 1960-2024 年。

df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 266 entries, 0 to 265 Data columns (total 70 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Country Name 264 non-null object 1 Country Code 266 non-null object 2 Indicator Name 266 non-null object 3 Indicator Code 266 non-null object 4 1960 264 non-null float64 5 1961 264 non-null float64 6 1962 264 non-null float64 7 1963 264 non-null float64 8 1964 264 non-null float64 9 1965 264 non-null float64 10 1966 264 non-null float64 11 1967 264 non-null float64 12 1968 264 non-null float64 13 1969 264 non-null float64 14 1970 264 non-null float64 15 1971 264 non-null float64 16 1972 264 non-null float64 17 1973 264 non-null float64 18 1974 264 non-null float64 19 1975 264 non-null float64 20 1976 264 non-null float64 21 1977 264 non-null float64 22 1978 264 non-null float64 23 1979 264 non-null float64 24 1980 264 non-null float64 25 1981 264 non-null float64 26 1982 264 non-null float64 27 1983 264 non-null float64 28 1984 264 non-null float64 29 1985 264 non-null float64 30 1986 264 non-null float64 31 1987 264 non-null float64 32 1988 264 non-null float64 33 1989 264 non-null float64 34 1990 265 non-null float64 35 1991 265 non-null float64 36 1992 265 non-null float64 37 1993 265 non-null float64 38 1994 265 non-null float64 39 1995 265 non-null float64 40 1996 265 non-null float64 41 1997 265 non-null float64 42 1998 265 non-null float64 43 1999 265 non-null float64 44 2000 265 non-null float64 45 2001 265 non-null float64 46 2002 265 non-null float64 47 2003 265 non-null float64 48 2004 265 non-null float64 49 2005 265 non-null float64 50 2006 265 non-null float64 51 2007 265 non-null float64 52 2008 265 non-null float64 53 2009 265 non-null float64 54 2010 265 non-null float64 55 2011 265 non-null float64 56 2012 265 non-null float64 57 2013 265 non-null float64 58 2014 265 non-null float64 59 2015 265 non-null float64 60 2016 265 non-null float64 61 2017 265 non-null float64 62 2018 265 non-null float64 63 2019 265 non-null float64 64 2020 265 non-null float64 65 2021 265 non-null float64 66 2022 265 non-null float64 67 2023 265 non-null float64 68 2024 265 non-null float64 69 2025 0 non-null float64 dtypes: float64(66), object(4) memory usage: 145.6+ KB

4. 数据清洗与预处理 (阶段 2)

原始数据为“宽格式”(一行一个国家,多年份平铺为多列),且包含大量非主权国家的汇总数据,无法
直接用于绘图。预处理分为以下核心步骤:

4.1 提取目标列

通过列表推导式筛选出所有列名为纯数字的列作为 year_cols ,保留 4 个属性列作为 attr_cols 。

year_cols=[iforiindf.columnsifi.isdigit()]#通过递推式筛选出所有列名为纯数字的列作为 year_cols#import numpy as np# year_cols=np.arange(1960,2026)attr_cols=['Country Name','Country Code','Indicator Name','Indicator Code']#保留 4 个属性列作为 attr_cols

4.2 剔除无效与汇总数据 (核心清洗)

  1. 删除空值:直接删除 Country Name 为 NaN 的行(此类行通常为 AFE/AFW 等大洲代码汇总)。
df=df.dropna(subset=['Country Name'])
  1. 黑名单过滤:定义包含 40+ 项的 black_list ,涵盖:
    全球及大洲汇总(如“世界”、“东亚与太平洋地区”、“撒哈拉以南非洲地区”等)。
    收入等级分类(如“高收入国家”、“中等收入国家”等)。
    非主权地区/领地(如“阿鲁巴”、“中国香港特别行政区”、“波多黎各”等)。
    使用 ~df[“Country Name”].isin(black_list) 进行反向过滤,最终精准保留 195 个 真
    实主权国家。
# 2.黑名单:剔除大洲、收入等级、发展区域汇总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(drop=True)print("过滤后剩余国家数量:",df["Country Name"].nunique())
过滤后剩余国家数量: 195

4.3 宽表转长表 (Reshape)

使用 pd.melt() 函数将数据结构转换为适合时序分析的“长格式”:
id_vars : 保持不变的属性列。
value_vars : 需要展开的年份列。
生成新列: Year (年份) 和 Population (人口数值)

# melt:宽转长df_long=pd.melt(df,id_vars=attr_cols,# 不变字段:国家名称、编码等value_vars=year_cols,# 需要拆开的年份列var_name="Year",# 拆分成成新列的列名:年份value_name="Population"# 对应值的新列名:人口)df_long.head()
Country NameCountry CodeIndicator NameIndicator CodeYearPopulation
0阿富汗AFG人口,总数SP.POP.TOTL19609035043.0
1安哥拉AGO人口,总数SP.POP.TOTL19605231654.0
2阿尔巴尼亚ALB人口,总数SP.POP.TOTL19601608800.0
3安道尔共和国AND人口,总数SP.POP.TOTL19609510.0
4阿拉伯联合酋长国ARE人口,总数SP.POP.TOTL1960131334.0

4.4 数据类型转换与最终清理

将 Year 列转换为 int 类型。

将 Population 列转换为 numeric 类型,并使用 dropna 剔除转换后产生的空值(如 2025 年
的 NaN 数据)。

最终得到包含 12,675 条有效记录的干净数据集,仅保留 Country Name , Year , Population 三
列。

df_clean=df_long[["Country Name","Year","Population"]]# 仅保留国家名称、年份、人口列df_clean["Year"]=df_clean["Year"].astype(int)# 将年份列转换为整数类型df_clean["Population"]=pd.to_numeric(df_clean["Population"])# 将人口列转换为数值类型df_clean.dropna(inplace=True)# 剔除包含 NaN 的行df_clean.head()
C:\Users\na\AppData\Local\Temp\ipykernel_23984\3147925960.py:2: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy df_clean["Year"]=df_clean["Year"].astype(int) # 将年份列转换为整数类型 C:\Users\na\AppData\Local\Temp\ipykernel_23984\3147925960.py:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy df_clean["Population"]=pd.to_numeric(df_clean["Population"]) # 将人口列转换为数值类型 C:\Users\na\AppData\Local\Temp\ipykernel_23984\3147925960.py:4: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy df_clean.dropna(inplace=True) # 剔除包含 NaN 的行
Country NameYearPopulation
0阿富汗19609035043.0
1安哥拉19605231654.0
2阿尔巴尼亚19601608800.0
3安道尔共和国19609510.0
4阿拉伯联合酋长国1960131334.0

5. 数据可视化与迭代优化 (阶段 4 - 6)

5.1 单年份横向柱状图测试 (阶段 4)

以 1990 年为例进行原型测试:
筛选 1990 年数据,按人口降序排列并取前 20 名。
使用 pyecharts.Bar 绘制,启用 reversal_axis() 将柱状图横向放置。
配置深色主题 ( ThemeType.DARK ),确保标签显示在柱子右侧 ( position=“right” ),验证基础渲
染逻辑无误。

# 数据准备test_df=df_clean[df_clean["Year"]==1990]test_df=test_df.sort_values(by="Population",ascending=False).head(20)#按人口排序,取前20名#绘制柱状图bar_test=(Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK))#设置主题为深色.add_xaxis(test_df["Country Name"].tolist())#国家名字作为横轴.add_yaxis("人口",test_df["Population"].tolist())#人口作为纵轴.reversal_axis()#将柱状图横向放置.set_global_opts(title_opts=opts.TitleOpts(title="1990年世界人口排名",pos_left="center"),#设置标题legend_opts=opts.LegendOpts(is_show=False),#隐藏图例框).set_series_opts(label_opts=opts.LabelOpts(position="right"))#设置标签显示在柱子右侧)#bar_test.render("bar_test.html") #将图表渲染为html文件,在浏览器中查看bar_test.render_notebook()
<div id="504c2a09894c44e99f38a924fa62473d" style="width:900px; height:500px;"></div>

5.2 Timeline 轮播基础版 (阶段 5)

遍历清洗后的所有唯一 Year 。
每年动态生成一个 Bar 实例,并通过 Timeline.add() 方法将其按年份追加到时间轴中。
配置基础轮播参数: is_auto_play=True , play_interval=700 (毫秒), is_loop_play=True 。
导出为 人口轮播_中文_基础版.html ,验证时序动画连贯性。

year_list=df_clean["Year"].unique().tolist()#获得年份列表#初始化时间线timeline=Timeline(init_opts=opts.InitOpts(width="1500px",height="820px",theme=ThemeType.DARK,bg_color="#0a0a0a"))#遍历年份列表,每个年份画一个柱状图,添加到时间线中foryearinyear_list:# 数据准备data_df=df_clean[df_clean["Year"]==year]data_df=data_df.sort_values(by="Population",ascending=False).head(20)#按人口排序,取前20名data_df=data_df.sort_values(by="Population",ascending=True)#再次升序排序,保证大的在上country=data_df["Country Name"].tolist()#国家名字列表population=data_df["Population"].tolist()#人口列表#绘制柱状图bar=(Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK))#设置主题为深色.add_xaxis(country)#国家名字作为横轴.add_yaxis("人口",population)#人口作为纵轴.reversal_axis()#将柱状图横向放置.set_global_opts(title_opts=opts.TitleOpts(title=f"{year}年世界人口排名",pos_left="center"),#设置标题legend_opts=opts.LegendOpts(is_show=False),#隐藏图例框).set_series_opts(label_opts=opts.LabelOpts(position="right"))#设置标签显示在柱子右侧)#将柱状图添加到时间线中timeline.add(bar,str(year))#配置基础轮播参数:自动播放、播放间隔600毫秒、循环播放timeline.add_schema(is_auto_play=True,play_interval=600,is_loop_play=True)timeline.render("基础轮播图.html")timeline.render_notebook()
<div id="adc22ca8bf5b4439a9e433e9d8ff3b26" style="width:1500px; height:820px;"></div>
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 4:44:40

novel-downloader:一键保存全网小说,打造你的永久数字图书馆

novel-downloader&#xff1a;一键保存全网小说&#xff0c;打造你的永久数字图书馆 【免费下载链接】novel-downloader 一个可扩展的通用型小说下载器。 项目地址: https://gitcode.com/gh_mirrors/no/novel-downloader 你是否经历过这样的场景&#xff1f;深夜追更的小…

作者头像 李华
网站建设 2026/6/15 12:31:29

如何为百度网盘Mac版解锁终极下载速度:完整配置指南

如何为百度网盘Mac版解锁终极下载速度&#xff1a;完整配置指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 你是否曾因百度网盘缓慢的下载速度而焦…

作者头像 李华
网站建设 2026/6/15 12:30:36

从CRISPR到表型:如何通过编辑uORF来微调植物性状(以玉米为例)

从CRISPR到表型&#xff1a;如何通过编辑uORF来微调植物性状&#xff08;以玉米为例&#xff09; 在玉米育种领域&#xff0c;传统方法往往通过全基因敲除或过表达来改变性状&#xff0c;但这种方式常导致"非黑即白"的表型变化。近年来&#xff0c;科学家发现上游开放…

作者头像 李华
网站建设 2026/6/15 12:31:48

深入解析EMC外部存储器控制器:时序配置、SDRAM管理与调试实战

1. 项目概述&#xff1a;为什么我们需要深入理解EMC&#xff1f; 在嵌入式系统开发&#xff0c;尤其是涉及音频处理、图像处理或任何需要大容量、高速数据交换的应用中&#xff0c;处理器与外部存储器&#xff08;如SDRAM、SRAM、Flash&#xff09;之间的通信桥梁——外部存储器…

作者头像 李华
网站建设 2026/6/15 12:32:28

如何在Draw.io中快速创建专业图表:Mermaid插件完整指南

如何在Draw.io中快速创建专业图表&#xff1a;Mermaid插件完整指南 【免费下载链接】drawio_mermaid_plugin Mermaid plugin for drawio desktop 项目地址: https://gitcode.com/gh_mirrors/dr/drawio_mermaid_plugin 你是否厌倦了在Draw.io中手动拖拽每一个图形元素&am…

作者头像 李华
网站建设 2026/6/15 19:01:54

【计算机毕业设计案例】基于 SpringBoot 的居民家政服务预约评价系统基于 SpringBoot 的家政预约管理系统(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华