数据来源:https://data.stats.gov.cn/easyquery.htm?cn=E0103
取下的数据:
百度网盘链接: https://pan.baidu.com/s/1JimyvpSi-LshMVhzx7x8Cg
提取码: nxax
代码参考:https://gallery.pyecharts.org/#/Map/china_gdp_from_1993_to_2018
完整代码:
from typing import List
import pandas as pd
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, Line
def get_year_chart(year: str):
map_data = [
[[x["name"], x["value"]] for x in d["data"]] for d in data if d["time"] == year
][0]
#图例
min_data, max_data = (minNum, maxNum)
c_data_mark: List = []
n_data_mark: List = []
i = 0
for x in time_list:
if x == year:
c_data_mark.append(c_total[i])
n_data_mark.append(n_total[i])
else:
c_data_mark.append("")
n_data_mark.append("")
i = i + 1
#地图
map_chart = (
Map()
.add(
series_name="",
data_pair=map_data,
#当前视角缩放比例
zoom=1,
center=[119.5, 34.5],
#是否显示标记图形
is_map_symbol_show=False,
# 图元样式配置项
itemstyle_opts={
"normal": {"areaColor": "#fdeff2", "borderColor": "#bf242a"},
"emphasis": {
"label": {"show": Timeline},
"areaColor": "rgba(255,255,255, 0.3)",
},
},
)
.set_global_opts(
title_opts=opts.TitleOpts(
title="" + str(year) + "全国各地常住人口分布情况(不含港澳台)",
subtitle="数据来源:国家统计局",
#主副标题间隔
item_gap=10,
pos_left="center",
pos_top="top",
title_textstyle_opts=opts.TextStyleOpts(
font_size=25, color="rgba(255,255,255, 0.9)"
),
subtitle_textstyle_opts=opts.TextStyleOpts(
font_size=15, 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="30",
pos_top="center",
range_color=["lightskyblue", "yellow", "orangered","red"],
textstyle_opts=opts.TextStyleOpts(color="#ddd"),
min_=min_data,
max_=max_data,
),
)
)
#城镇人口变化
line_chart = (
Line()
.add_xaxis(time_list)
.add_yaxis('', c_total,
linestyle_opts=opts.LineStyleOpts(color='orange'))
.add_yaxis("", n_total,
linestyle_opts=opts.LineStyleOpts(color='green'))
.add_yaxis(
"",
c_data_mark,
markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]),
)
.add_yaxis(
"",
n_data_mark,
markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]),
)
.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(
title="城镇和农村人口变化2013-2021年",
subtitle="城镇:橘色,农村:绿色",
# 主副标题间隔
item_gap=10,
pos_left="70%", pos_top="5%"
),
legend_opts=opts.LegendOpts(
is_show=True,
pos_left='75%',
pos_bottom='88%'
),
xaxis_opts=opts.AxisOpts(
is_show=True
),
yaxis_opts=opts.AxisOpts(
name="人",
min_=40000,
),
)
)
#柱状图
bar_x_data = [x[0] for x in map_data]
bar_y_data = [{"name": x[0], "value": x[1][0]} for x in map_data]
bar = (
Bar()
.add_xaxis(xaxis_data=bar_x_data)
.add_yaxis(
series_name="",
y_axis=bar_y_data,
label_opts=opts.LabelOpts(
is_show=True, position="right", formatter="{b} : {c}"
),
)
.reversal_axis()
.set_global_opts(
xaxis_opts=opts.AxisOpts(
max_=maxNum, axislabel_opts=opts.LabelOpts(is_show=False)
),
yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(is_show=False)),
tooltip_opts=opts.TooltipOpts(is_show=False),
visualmap_opts=opts.VisualMapOpts(
is_calculable=True,
dimension=0,
pos_left="30",
pos_top="25",
range_text=["High", "Low"],
range_color=["lightskyblue", "yellow", "orangered","red"],
textstyle_opts=opts.TextStyleOpts(color="#ddd"),
min_=min_data,
max_=max_data,
),
)
)
#饼图
pie_data = [[x[0], x[1][0]] for x in map_data]
pie = (
Pie()
.add(
series_name="",
data_pair=pie_data,
radius=["15%", "35%"],
center=["80%", "82%"],
itemstyle_opts=opts.ItemStyleOpts(
border_width=1, border_color="rgba(0,0,0,0.3)"
),
)
.set_global_opts(
tooltip_opts=opts.TooltipOpts(is_show=True, formatter="{b} {d}%"),
legend_opts=opts.LegendOpts(is_show=False),
)
)
#将所有图表放在一起
grid_chart = (
Grid()
.add(
bar,
grid_opts=opts.GridOpts(
pos_left="10", pos_right="45%", pos_top="50%", pos_bottom="5"
),
)
.add(
line_chart,
grid_opts=opts.GridOpts(
pos_left="65%", pos_right="80", pos_top="10%", pos_bottom="50%"
),
)
.add(pie, grid_opts=opts.GridOpts(pos_left="45%", pos_top="60%"))
.add(map_chart, grid_opts=opts.GridOpts())
)
return grid_chart
if __name__ == "__main__":
#读入数据
data1 = pd.read_excel(r"人口.xlsx", sheet_name='年末常住人口')
c_data = pd.read_excel(r"人口.xlsx", sheet_name='城镇人口', usecols=[1,2,3,4,5,6,7,8,9])
n_data = pd.read_excel(r"人口.xlsx", sheet_name='农村人口', usecols=[1,2,3,4,5,6,7,8,9])
#统计每一年的城镇人口和农村人口总数,用来画折线图
c_total = c_data.sum().to_list()
n_total = n_data.sum().to_list()
#计算每个城市人口占总人口的百分比
zb_list = [str(d) + "年占比" for d in range(2013, 2022)]
time_list = [str(d) + "年" for d in range(2013, 2022)]
for i in time_list:
for j in zb_list:
data1[j] = (data1[i] / data1[i].sum()) * 100
# 集合数据
data = []
#取出省份名称
cs_lt = data1['地区'].values.tolist()
#计算一共有多少的省份
cs_len = len(cs_lt)
'''利用for循环将数据集成如下的形式,方便后序制图
[
{"time":"年份",
"data":[{"name": "省份", "value": [人口数量, 占比, "省份"]},
{"name": "省份", "value": [人口数量, 占比, "省份"]},······
]
},
{"time":"年份",
"data":[{"name": "省份", "value": [人口数量, 占比, "省份"]},······
]},······
]
'''
for k1 in range(9):
#取出同一年不同省份的数据
lt1 = data1[[time_list[k1], zb_list[k1], '地区']].values.tolist()
dt_list = []
#将不同省份组合为字典的形式
for k2 in range(cs_len):
dt13 = {'name': cs_lt[k2], 'value': lt1[k2]}
dt_list.append(dt13)
#将年份和每一年的数据组合为字典的形式
dt = {"time": time_list[k1], "data": dt_list}
#添加到data列表里,即全部集成在一起
data.append(dt)
# 渲染颜色组件的最大最小值
maxNum = 20000
minNum = 0
#画图
timeline = Timeline(
init_opts=opts.InitOpts(width="1600px", height="900px", page_title='2013-2021年的人口变化(不含港澳台地区)',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="60",
label_opts=opts.LabelOpts(is_show=True, color="#fff"),
)
timeline.render("2013-2021年的人口变化(不含港澳台地区).html")