pyecharts的Grid和Page—人口变化图

2021-04-23  本文已影响0人  Hobbit的理查德

做完上个婚姻数据后,【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年人口数及构成变化.gif

2005-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年分省份年龄结构变化.gif

4、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

虽然北京、上海的老人占比高,但是,年轻人也不少,因此,总抚养比一直差不多是倒数。

而贵州、广西、四川等年轻人的负担(总抚养比)一直都还挺高的。

上一篇下一篇

猜你喜欢

热点阅读