python可视化--实战案例1各州各种族人口数分布

数据来源

设置画板

import warnings
import matplotlib.pyplot as plt
%matplotlib inline

# 屏蔽代码运行过程中出现的警告信息,主要是屏蔽 pandas 的 .loc 警告问题
warnings.filterwarnings("ignore")

fontsize = 20
plt.rcParams['xtick.labelsize'] = fontsize
plt.rcParams['ytick.labelsize'] = fontsize
plt.rcParams['axes.labelsize'] = fontsize
plt.rcParams['axes.titlesize'] = fontsize
plt.rcParams['legend.fontsize'] = fontsize
plt.rcParams['legend.frameon'] = False  # 去除图例边框
plt.rcParams['axes.unicode_minus'] = False  # 显示负数
plt.rcParams['axes.spines.right'] = False  # 去除右侧坐标轴
plt.rcParams['axes.spines.top'] = False  # 去除顶部坐标轴

数据准备

#数据导入
import pandas as pd
df = pd.read_csv('https://labfile.oss.aliyuncs.com/courses/3023/American_Race_Gender_Population.csv')
df.head()
#认识数据:本数据集来源于美国人口普查局与美国国家卫生统计中心,该数据集统计了美国自 1990 至 2019 年期间,各年度全美 51 州各年度性别(Gender)、种族(Race)、年龄段(Age Group)的人口数(Population),数据集中的 Mean Age 字段根据 Age Group 求算术平均得到。

各州各种族人口数分布

目标:想做一个在不同州不同种族上人口数的散点图分布。步骤:

  1. 将数据集按照州(State)、种族(Race)进行人口数(Population)聚合并按照人口数升序排序。
  2. 聚合后,将聚合数据集中的 State、Race 特征分别映射至散点图 x、y 坐标,将 Population 人口数特征映射至点的颜色(c)和大小(s)。
  3. 还有年份这一特征,选择最大最小两个年份(1990 和 2019 )作图。
plt.rcParams['figure.figsize'] = (20, 5)

for year in [1990, 2019]:
    data = df.loc[df['Year'] == year]

    # 各州按照总人口数升序排序
    state_order = data.groupby(['State'])[
        'Population'].sum().sort_values().index
    # 将 State 字段设置为有序字段,astype:转换数组的数据类型。
    data['State'] = data['State'].astype(
        pd.api.types.CategoricalDtype(state_order, ordered=True))

    # 获取州、种族的聚合结果,并按州升序排序
    data = data.groupby(['State', 'Race'], as_index=False)[
        'Population'].sum().sort_values(['State'])

    plt.scatter(
        x=data['State'],
        y=data['Race'],
        c=data['Population'],
        s=data['Population']*0.0001,
        ec='tab:blue',
        cmap=plt.cm.Accent,
        alpha=0.8)
	#c指colors颜色,s表示点的大小,cmap指定某个colormap值
	#plt.gca可以通过这个改图标的边框属性
    ax = plt.gca()

    # 将x轴刻度标签旋转90度,刻度字太多
    ax.tick_params(axis='x', rotation=90)
    # 调节y轴显示范围
    ax.set_ylim(-0.5, 3.5)
    plt.title('Population Distribution of States of American in Year %d' % year)
    plt.show()  # 关闭当前图层以绘制下一幅图

做出图了最好给出一些结论。
例如,州对比:在2019年,人口数最多的州是哪些,最少的州是哪些。
种族对比:不同种类的人口数是怎么排名的
各州人口变迁:1990年与2019年,有哪些变化趋势

人口与人口增长率

通过数据透视计算1990到2019的各州人口增长率(Pupulation Changed %),通过数据聚合计算各州 2019 年总人口数(Population)

data = df.loc[(df['Year'] == 1990) | (df['Year'] == 2019)]
# 计算美国各州人口增长率
#pivot_table数据透视表,可以查询每个参数含义
pop_change = data.pivot_table(
    index='State', columns='Year', values='Population',aggfunc='sum')
pop_change['Population Changed/%'] = 100 * \
    (pop_change[2019]-pop_change[1990])/pop_change[1990]
pop_change

# 计算美国2019年各州总人口数
pop = df.loc[df['Year'] == 2019].groupby(['State'])['Population'].sum()

# # 将人口总数与人口增长率数据合并并筛选需要的特征
data = pd.concat([pop, pop_change], axis=1)[
    ['Population', 'Pupulation Changed/%']]

data.head()

将人口总数与人口增长率数据分别映射到散点图 x、y 坐标及点颜色和大小

plt.rcParams['figure.figsize'] = (14, 7)
x = data['Population']
y = data['Pupulation Changed/%']

#散点图plt.scatter中,marker表示点的形状,s表示点的大小,
#c表示颜色,cmap指定某个colormap值(颜色图),alpha指透明度
plt.scatter(x, y,
            marker='o', 
            s=data['Population']*0.0001, 
            c=data['Population'],
            cmap=plt.cm.Blues_r,
            edgecolors='gray')  # 散点图标记的轮廓及填充颜色

plt.xlabel('Population')
plt.ylabel('Pupulation Changed /%')
#axhline()函数用于绘制平行于x轴的水平参考线.y是水平参考线的出发点
plt.axhline(y=y.mean(),color='tab:red',label='Avg Changed Ratio: %.2f%%'%(y.mean()))

#写成图例
plt.legend()

s = data.index
#plt.text给每个点加标签。
#对plt.text(x, y, s, fontsize, verticalalignment,horizontalalignment,rotation , **kwargs)
#x,y表示标签添加的位置。s表示标签的符号,字符串格式。fontsize顾名思义就是你加标签字体大小了,取整数。verticalalignment表示垂直对齐方式 ,horizontalalignment表示水平对齐方式 ,可以填 ‘center’ , ‘right’ ,‘left’ 等。rotation表示标签的旋转角度,以逆时针计算,取整
for xpos, ypos, text in zip(x, y, s):
    plt.text(xpos, ypos, text, size=16,va='bottom',ha='left')

plt.title('Population & Pupulation Changed (Compared to Year 1990) of American')

依旧根据图形写成分析结果:
例如,平均增长率y.mean(),对于各个州,哪些达到了平均增长率,哪些州没有。增长率最大/小的州是哪些

对于人口数量较少和人口增速不明显的多数州,其数据被压缩至平均线以下的 0 轴附近,可通过将数据进行对数变换(log)的方法,将数据均匀分布。

##x,y数值取np.log 对数,其他步骤和上面一样。
import numpy as np

plt.rcParams['figure.figsize'] = (14, 7)

x = np.log(data['Population'])
y = np.log(data['Pupulation Changed/%'])

plt.scatter(x, y,
            marker='o',
            s=data['Population']*0.0001,
            c=data['Population'],
            cmap=plt.cm.Blues,
            label='Changed of States of American',
            edgecolors='gray')  # 散点图标记的轮廓及填充颜色

plt.xlabel('log (Population)')
plt.ylabel('log (Pupulation Changed /%)')


s = data.index

for xpos, ypos, text in zip(x, y, s):
    plt.text(xpos, ypos, text, size=16, va='bottom', ha='left')

plt.title('Population & Pupulation Changed (Compared to Year 1990) of American')

数据在对数坐标系下,分散变得十分均匀,各数据点被均匀拉开。下次作图时数据现实集中时,考虑取对数。

种族及人口变化率

白人
在前面图示中,人口中白人占据了极大部分。所以计算各州人口增长率与白人增长率。

和上面的计算增长率的代码相似

data = df.loc[(df['Year'] == 1990) |(df['Year'] == 2019) ]

# 计算美国各州人口增长率
pop_change=data.pivot_table(index='State',columns='Year',values='Population',aggfunc='sum')
pop_change['Pupulation Changed/%']=100*(pop_change[2019]-pop_change[1990])/pop_change[1990]
pop_change

# 计算美国各州白人人口增长率
white_change=data.loc[data['Race']=='White'].pivot_table(index='State',columns='Year',values='Population',aggfunc='sum')
white_change['White Changed/%']=100*(white_change[2019]-white_change[1990])/white_change[1990]
white_change

# 将人口增长率与白人增长率数据合并
changed=pd.concat([pop_change,white_change],axis=1)

# 挑选主要字段
changed=changed[['Pupulation Changed/%','White Changed/%']]

# 展示前5行数据
changed.head()

得到各州总人口增长率和白人增长率后,比较一下增长率情况。将各州人口增长率与各州白人增长率分别映射到散点图,通过 np.ployfit 拟合其关系并绘制拟合曲线,同时绘制 y = x 曲线进行对比。

plt.rcParams['figure.figsize'] = (10, 6)
x = changed['Pupulation Changed/%']
y = changed['White Changed/%']

# 绘制各州人口及白人增长数据
plt.scatter(x, y,
            marker='o',s=120,
            label='Changed of States of American',
            edgecolors='tab:red',facecolor='white') # 散点图标记的轮廓及填充颜色

plt.xlabel('Pupulation Changed /%')
plt.ylabel('White Race Changed /%')

# 拟合增长率曲线,对散点进行拟合,返回元组(k,b)
f_1 = np.polyfit(x, y,deg=1)

# 绘制拟合的增长曲线
plt.plot(x,np.polyval(f_1, x),
         lw=2,color='tab:orange',label='Increase Ratio of White Race')

# 绘制平衡增长曲线  y=x
plt.plot(np.linspace(0,150,20),
         np.linspace(0,150,20),
         color='tab:blue',
         label='Increase Ratio of Balance',ls='--',lw=3)
#前面的label没有反应,只有plt.legend()才会真正标记上去
plt.legend()
#plt.text是给点加标注,给异常点加标注是哪个州
plt.text(25,75,'District of Columbia',fontsize=20,color='tab:red',ha='center',va='bottom')
plt.text(155,120,'Nevada',fontsize=20,color='tab:red',ha='center',va='bottom')

plt.title('Population & White Race Changed of States of American')

依旧看图给结论:种族增长率与人口增长率的线性关系如何,与y=x相比如何,异常点的情况如何
所有种族
用上面白色人种的方法处理全部种族,用一个for循环处理所有种族

data = df.loc[(df['Year'] == 1990) | (df['Year'] == 2019)]

# 计算美国各州人口增长率
changed = data.pivot_table(index='State', columns='Year', values='Population',aggfunc='sum')
changed['Pupulation Changed /%'] = 100 * \
    (changed[2019]-changed[1990])/changed[1990]


race_columns = ['Pupulation Changed /%']
for race in ['American Indian or Alaska Native', 'Asian or Pacific Islander', 'Black or African American', 'White']:

    # 计算美国各种族人口增长率
    race_change = data.loc[data['Race'] == race].pivot_table(
        index='State', columns='Year', values='Population',aggfunc='sum')
    race_change[race+' Changed /%'] = 100 * \
        (race_change[2019]-race_change[1990])/race_change[1990]

    # 将人口增长率与各族人口增长率数据合并
    changed = pd.concat([changed, race_change], axis=1)

    race_columns.append(race+' Changed /%')

# 挑选主要字段
changed = changed[race_columns]

# 展示前5行数据
changed.head()

从图表可以看出:
每个种族的增长率变化情况,与总人口的增长率相比如何
种族增长率中最高的是哪个种族,最低的是哪个种族
异常点情况

人口结构

各年龄组构成的人口结构
将平均年龄字段按照 20,40,70 三个节点进行切分,获得 青年、壮年、中年、老年 4 个年龄分组段,聚合各分组段人数后用漏斗图可视化 1990 年的人口结构。
下图是1990年人口结构漏洞图

!pip install pyecharts==1.7.1

from pyecharts import options as opts
from pyecharts.charts import Funnel

data = df.loc[df['Year'] == 1990]
# 将平均年龄进行数据切分,生成新的组
#pd.cut用于将数据值按照值本身进行分段并排序到 bins 中
data['Age Group3'] = pd.cut(
    data['Mean Age'],
    bins=[0, 20, 40, 70, 100],
    labels=['Youth(<20)', 'Prime(20-40)', 'Middle(40-70)', 'Old(>70)'])
data = data.groupby(['Age Group3'], as_index=False)['Population'].sum()
data['Population'] = data['Population']/np.sum(data['Population'])*100

funel = Funnel()
funel.add(
    " ",
    [list(z) for z in zip(data['Age Group3'], data['Population'])],
    sort_='none',
    label_opts=opts.LabelOpts(position="inside"),
)
funel.set_global_opts(
    title_opts=opts.TitleOpts(
        title="Population Struction of American Year 1990",),
    legend_opts=opts.LegendOpts(
        pos_top='5%', textstyle_opts=opts.TextStyleOpts(font_size=15)),
)
funel.render_notebook()

同样的,做2019年的人口结构漏斗图

data = df.loc[df['Year'] == 2019]
data['Age Group3'] = pd.cut(
    data['Mean Age'],
    bins=[0, 20, 40, 70, 100],
    labels=['Youth(<20)', 'Prime(20-40)', 'Middle(40-70)', 'Old(>70)'])
data = data.groupby(['Age Group3'], as_index=False)['Population'].sum()
data['Population'] = data['Population']/np.sum(data['Population'])*100

funel = Funnel()
funel.add(
    " ",
    [list(z) for z in zip(data['Age Group3'], data['Population'])],
    sort_='none',
    label_opts=opts.LabelOpts(position="inside"),
)
funel.set_global_opts(
    title_opts=opts.TitleOpts(
        title="Population Struction of American Year 2019",),
    legend_opts=opts.LegendOpts(
        pos_top='5%', textstyle_opts=opts.TextStyleOpts(font_size=15)),
)
funel.render_notebook()

性别分布

fig, axs = plt.subplots(1, 3, figsize=(15, 6), sharey=True, sharex=True)

for i, year in enumerate([1990, 2010, 2019]):
    ax = axs[i]
    data = df.loc[df['Year'] == year].groupby(
        ['Gender', 'Race'], as_index=False)['Population'].sum().sort_values('Population')
    data

    ax.scatter(
        x=data['Gender'],
        y=data['Race'],
        c=data['Gender'].apply(lambda x: 'tab:red' if x ==
                               'Female' else 'tab:blue'),
        s=data['Population']*0.00007,
        ec='gray',
    )

    ax.set_ylim(-0.5, 4)
    ax.set_xlim(-1, 1.5)
    ax.set_title('Year %d' % year)

    if i > 0:
        ax.spines['left'].set_visible(False)

fig.suptitle('Population Distribution Varies with Gender of USA',
             size=25, va='bottom')
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值