美文网首页
pyecharts的Grid和Page—人口变化图

pyecharts的Grid和Page—人口变化图

作者: Hobbit的理查德 | 来源:发表于2021-04-23 21:47 被阅读0次

    做完上个婚姻数据后,【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

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

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

    相关文章

      网友评论

          本文标题:pyecharts的Grid和Page—人口变化图

          本文链接:https://www.haomeiwen.com/subject/ptmhrltx.html