pyecharts的Grid和Page—人口变化图
做完上个婚姻数据后,【python实战】pyecharts时间轮播图——结婚了么?
就去国家统计局下了2005-2019年的人口方面的数据,继续练一练pyecharts。
一、数据准备
所有要导入的包
import os
import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import Bar, Line, Pie, Timeline, Grid, Funnel, Map, Page
数据准备
# 数据导入
current_dir = os.getcwd()
df_all = pd.read_excel(current_dir + '\\excel\\' + '人口数及构成.xlsx')
df_age = pd.read_excel(current_dir + '\\excel\\' + '人口年龄结构和抚养比.xlsx')
# 数据合并
df_merge = pd.merge(df_all,df_age,how="left")
df_merge.to_excel('人口及年龄结构和抚养比.xlsx',index=0)
# 提取数据
df_all['总人口(年末)(单位:亿人)'] = round(df_all['总人口(年末)(单位:万人)']/10000,2)
df_all = df_all[-15:]
# print(df_all.columns.values.tolist())
# print(df_all.head(5))
df_age = df_age[-15:]
# 数据准备
year_ls = [str(i)+'年' for i in list(df_all['年份\n'])]
num_ls = list(df_all['总人口(年末)(单位:亿人)'])
male_ls = list(df_all['男比重(%)'])
female_ls = list(df_all['女比重(%)'])
city_ls = list(df_all['城镇比重(%)'])
country_ls = list(df_all['乡村比重(%)'])
child_ls = list(df_age['0-14岁比重(%)'])
adult_ls = list(df_age['15-64岁比重(%)'])
older_ls = list(df_age['65岁及以上比重(%)'])
二、数据结果
1、2005-2019年人口数及构成变化
用Grid将静态的折线图Line,和动态的3个饼图Pie的时间轮播图Timeline组合在一个页面里,看看这15年全国的人口数量变化及结构变化。
def line_pie_timeline():
line = (
Line()
.add_xaxis(year_ls)
.add_yaxis("", num_ls, yaxis_index = 1)
.set_series_opts(
label_opts=opts.LabelOpts(is_show = True, position = "top", font_size = 12),
areastyle_opts=opts.AreaStyleOpts(opacity = 0.5),)
.set_global_opts(
title_opts=opts.TitleOpts(title="2005-2019年总人口数(年末)"),
xaxis_opts=opts.AxisOpts(boundary_gap = False),
yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(formatter="{value} 亿人"),
min_ = 12, max_ = 15),
)
)
timeline = Timeline(init_opts=opts.InitOpts(width='1100px',height='700px'))
for i in range(len(year_ls)):
pie1 = (
Pie()
.add("",
[list(z) for z in zip(['城镇','乡村'], [city_ls[i],country_ls[i]])],
radius = ['15%','30%'],
rosetype = "radius",
center = ["30%","75%"]
)
.set_colors(["blue", "green"])
.set_global_opts(
title_opts=opts.TitleOpts(title=year_ls[i]+"城镇及乡村占比(%)", pos_left = "0%",pos_top="55%",),
legend_opts = opts.LegendOpts(pos_left = "0%",pos_top="60%",))
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
)
pie2 = (
Pie()
.add("",
[list(z) for z in zip(['男','女'], [male_ls[i],female_ls[i]])],
radius = ['15%','30%'],
rosetype = "radius",
center = ["70%","75%"]
)
.set_colors(["blue", "green"])
.set_global_opts(
title_opts=opts.TitleOpts(title=year_ls[i]+"男女占比(%)", pos_right = "5%",pos_top="55%",),
legend_opts = opts.LegendOpts(pos_left = "80%",pos_top="60%",))
.set_series_opts(
label_opts=opts.LabelOpts(formatter="{b}: {c}")
)
)
pie0 = (
Pie()
.add("",
[list(z) for z in zip(['0-14岁','15-64岁', '65岁及以上'], [child_ls[i],adult_ls[i],older_ls[i]])],
radius = ['15%','30%'],
rosetype = "radius",
center = ["70%","30%"]
)
.set_colors(["blue", "green"])
.set_global_opts(
title_opts=opts.TitleOpts(title=year_ls[i]+"年龄结构占比(%)", pos_right = "5%",pos_top="0%",),
legend_opts = opts.LegendOpts(pos_left = "70%",pos_top="5%",))
.set_series_opts(
label_opts=opts.LabelOpts(formatter="{b}: {c}")
)
)
grid = (
Grid()
.add(line,
grid_opts=opts.GridOpts(
pos_right="50%",
pos_bottom="55%",
is_contain_label=False
),
)
.add(pie0,
grid_opts=opts.GridOpts(
pos_left="80%",
pos_right="5%",
pos_bottom="55%",
is_contain_label=False
),
)
.add(pie1,
grid_opts=opts.GridOpts(
pos_left="80%",
pos_top="30%",
is_contain_label=False
),
)
.add(pie2,
grid_opts=opts.GridOpts(
pos_left="80%",
pos_top="30%",
is_contain_label=False
),
)
)
timeline.add(grid,year_ls[i])
timeline.add_schema(
is_auto_play=True,
play_interval=1000,
pos_left="5%",
pos_right="5%",
pos_bottom="0",
)
timeline.render("2005-2019年人口数及构成变化.html")
line_pie_timeline()
结果如下图所示。
2005-2019年人口数及构成变化.gif2005-2019年人口真的是逐渐增加。
65岁及以上占比也越来越多。
城镇占比变化增加得很明显。
男女占比倒是变化不明显,但男的一直比女的多……
2、2005-2019年抚养比情况变化
接着,做个静态的条形图Bar,看看2005-2019年的抚养比变化情况。
其中,少儿抚养比 = 0-14岁人口数/15-64岁人口数;
老年抚养比 = 65岁及以上人口数/15-64岁人口数;
总抚养比 = 少儿抚养比 + 老年抚养比
# 数据准备
child_raise_ls = list(df_age['少儿抚养比(%)'])
older_raise_ls = list(df_age['老年抚养比(%)'])
total_raise_ls = list(df_age['总抚养比(%)'])
def stackbar():
bar = (
Bar(init_opts=opts.InitOpts(width='1100px',height='500px'))
.add_xaxis(year_ls)
.add_yaxis('少儿抚养比',child_raise_ls,stack="stack1")
.add_yaxis('老年抚养比',older_raise_ls,stack="stack1")
.set_global_opts(title_opts=opts.TitleOpts(title="2005-2019年抚养比情况变化(%)"),
yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(formatter="{value} %")),)
.set_series_opts(label_opts=opts.LabelOpts(position="inside"))
)
line = Line().add_xaxis(year_ls).add_yaxis('总抚养比',total_raise_ls)
linebar = bar.overlap(line)
linebar.render("2005-2019年抚养比情况变化.html")
stackbar()
结果如下图。
2005-2019年抚养比情况变化.gif按照郑老师的说法,2010年是个好时候啊。
之后每年的抚养比在逐渐增加,主要是老年抚养比增加得明显。
3、2005-2019年分省份年龄结构变化
然后,做个静态的堆积条形图Bar,看看不同省份不同年份的年龄结构变化情况。
def stackbar_timeline():
timeline = Timeline(init_opts=opts.InitOpts(width='1200px',height='700px'))
for i in range(2005,2020):
province = pd.read_excel(current_dir + '\\excel\\' + '2005-2019分地区人口年龄结构和抚养比.xlsx', sheet_name=str(i))
province = province[~(province['地区'].isnull())]
province['地区'] = province['地区'].str.replace(' ','').replace(' ','')
province=province[province['地区']!='全国']
province['0-14岁占比(%)'] = round(province['0-14岁人口数']/province['人口数(人)']*100,2)
province['15-64岁占比(%)'] = round(province['15-64岁人口数']/province['人口数(人)']*100,2)
province['65岁及以上占比(%)'] = round(province['65岁及以上人口数']/province['人口数(人)']*100,2)
province.sort_values(by=['65岁及以上占比(%)'],ascending=(False), inplace=True, ignore_index=True)
dq = list(province['地区'])[::-1]
child = list(province['0-14岁占比(%)'])[::-1]
adult = list(province['15-64岁占比(%)'])[::-1]
older = list(province['65岁及以上占比(%)'])[::-1]
bar = (
Bar()
.add_xaxis(dq)
.add_yaxis('0-14岁',child,stack='stack1')
.add_yaxis('15-64岁',adult,stack='stack1')
.add_yaxis('65岁及以上',older,stack='stack1')
.reversal_axis()
.set_series_opts( # 系列配置项
label_opts=opts.LabelOpts(position="inside"))
.set_global_opts( # 全局配置项
title_opts=opts.TitleOpts(title=str(i)+"年分地区人口年龄结构变化(单位:%)",pos_left="5%"),
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(is_show=False),
axisline_opts=opts.AxisLineOpts(is_show=False),
axistick_opts=opts.AxisTickOpts(is_show=False),),
legend_opts = opts.LegendOpts(pos_left = "30%",pos_top="5%",))
)
timeline.add(bar,str(i)+'年')
timeline.add_schema(
play_interval=1500, # 轮播速度
is_timeline_show=True, # 是否显示 timeline 组件
is_auto_play=True, # 是否自动播放
pos_bottom="0%",
pos_left='5%',
)
timeline.render("2005-2019年分省份年龄结构变化.html")
stackbar_timeline()
结果如下图所示。
每年按照各个省份的65岁及以上的占比,即老人占比情况进行排序。
四川、重庆、辽宁、北京、上海等老人占比一直都还挺大的。
2005-2019年分省份年龄结构变化.gif4、2005-2019年分省份抚养比变化
这次用Page将Map图和堆积条形图Bar拼在一起,看看不同省份不同年份的抚养比变化。
最开始是打算用Grid组合起来的,但是,如果Bar的set_global_opts中设置visualmap_opts的话,条形图的颜色也会被渲染成连续的颜色。如果不设置的话,Map中的颜色就显示不出来。
最后,分别设置Map和Bar的大小,然后用Page拼接起来,不同浏览器显示的效果可能会不一样哟。
def timeline_map() -> Map:
timeline = Timeline(init_opts=opts.InitOpts(width='900px',height='700px'))
for i in range(2005,2020):
province = pd.read_excel(current_dir + '\\excel\\' + '2005-2019分地区人口年龄结构和抚养比.xlsx', sheet_name=str(i))
province = province[~(province['地区'].isnull())]
province['地区'] = province['地区'].str.replace(' ','').replace(' ','')
province=province[province['地区']!='全国']
province['少儿抚养比(单位:%)'] = round(province['0-14岁人口数']/province['15-64岁人口数']*100,2)
province['老年抚养比(单位:%)'] = round(province['65岁及以上人口数']/province['15-64岁人口数']*100,2)
province['总抚养比(单位:%)'] = province['少儿抚养比(单位:%)']+province['老年抚养比(单位:%)']
province.sort_values(by=['总抚养比(单位:%)'],ascending=(False), inplace=True, ignore_index=True)
dq = list(province['地区'])[::-1]
total_raise = list(province['总抚养比(单位:%)'])[::-1]
min_data = min(total_raise)
max_data = max(total_raise)
map_chart = (
Map()
.add(
series_name="",
data_pair=[list(z) for z in zip(dq,total_raise)],
zoom=1,
center=[105, 34.5],
is_map_symbol_show=False,
)
.set_global_opts(
title_opts=opts.TitleOpts(
title=str(i) + '年抚养比变化(单位:%)',
pos_left="center",
pos_top="top",
title_textstyle_opts=opts.TextStyleOpts(
font_size=25,
# color=titlecolor
),
),
tooltip_opts=opts.TooltipOpts(
is_show=False,
),
visualmap_opts=opts.VisualMapOpts(
is_calculable=True,
dimension=0,
pos_left="2%",
pos_bottom="20%",
range_text=["总抚养比(%)", ""],
range_color=['DeepSkyBlue','Orange','Red'],
textstyle_opts=opts.TextStyleOpts(color="black",font_size=10),
min_=min_data,
max_=max_data,
),
)
)
timeline.add(map_chart,str(i)+'年')
timeline.add_schema(
play_interval=1500, # 轮播速度
is_timeline_show=True, # 是否显示 timeline 组件
is_auto_play=True, # 是否自动播放
pos_left="0",
pos_right="0"
)
return timeline
def timeline_bar() -> Bar:
timeline = Timeline(init_opts=opts.InitOpts(width='400px',height='700px'))
for i in range(2005,2020):
province = pd.read_excel(current_dir + '\\excel\\' + '2005-2019分地区人口年龄结构和抚养比.xlsx', sheet_name=str(i))
province = province[~(province['地区'].isnull())]
province['地区'] = province['地区'].str.replace(' ','').replace(' ','')
province=province[province['地区']!='全国']
province['少儿抚养比(单位:%)'] = round(province['0-14岁人口数']/province['15-64岁人口数']*100,2)
province['老年抚养比(单位:%)'] = round(province['65岁及以上人口数']/province['15-64岁人口数']*100,2)
province['总抚养比(单位:%)'] = province['少儿抚养比(单位:%)']+province['老年抚养比(单位:%)']
province.sort_values(by=['总抚养比(单位:%)'],ascending=(False), inplace=True, ignore_index=True)
dq = list(province['地区'])[::-1]
child_raise = list(province['少儿抚养比(单位:%)'])[::-1]
older_raise = list(province['老年抚养比(单位:%)'])[::-1]
bar = (
Bar()
.add_xaxis(dq)
.add_yaxis('少儿抚养比',child_raise,stack='stack1')
.add_yaxis('老年抚养比',older_raise,stack='stack1')
.reversal_axis()
.set_series_opts( # 系列配置项
label_opts=opts.LabelOpts(position="inside"))
.set_global_opts( # 全局配置项
xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(is_show=False),
axisline_opts=opts.AxisLineOpts(is_show=False),
axistick_opts=opts.AxisTickOpts(is_show=False),),
legend_opts = opts.LegendOpts(pos_top="5%",)
)
)
timeline.add(bar,str(i)+'年')
timeline.add_schema(
play_interval=1500, # 轮播速度
is_timeline_show=False, # 是否显示 timeline 组件
is_auto_play=True, # 是否自动播放
)
return timeline
def page_simple_layout():
page = Page(layout=Page.SimplePageLayout)
page.add(
timeline_map(),
timeline_bar(),
)
page.render("2005-2019年分省份抚养比变化.html")
page_simple_layout()
结果如下图所示。
2005-2019年分省份抚养比变化.gif虽然北京、上海的老人占比高,但是,年轻人也不少,因此,总抚养比一直差不多是倒数。
而贵州、广西、四川等年轻人的负担(总抚养比)一直都还挺高的。