【Python数据分析及可视化】美国犯罪监禁数据分析与可视化


前言

上世纪70年代以来,美国由于大规模监禁,被冠以“监狱国”之名。根据联合国统计数据显示,2020年美国以1675400余人的囚犯数量,位居全球监禁人数首位。仅占世界人口数5%的美国,却居住着世界上超25%的囚犯。本篇正是基于该背景,分析相关数据集,揭示大规模监禁下的公共安全问题。

以2001年到2016年期间的美国犯罪与监禁情况数据为研究对象,借助Python中的多种数据可视化技术,从“州别”、“类型”、“性别”、“年龄”四个维度研究美国犯罪情况。监禁情况方面,主要从美国国内监禁率变化与国外监禁率对比角度切入,并初步探索犯罪率与监禁率关系。

数据来源:
1.kaggle 美国犯罪与监禁 https://www.kaggle.com/datasets/christophercorrea/prisoners-and-crime-in-united-states
2.联合国犯罪与囚禁数据(https://dataunodc.un.org/dp-prisons-persons-held)

一、数据描述

两个犯罪集各字段特征及其含义
1.美国各州犯罪与监禁情况
特征名称 特征含义
jurisdiction 犯罪管辖权所在州
includes_jails 是否包括监狱
year 年份
prisoner_count 在押囚犯年终人数
crime_reporting_change 犯罪报告是否变化
crimes_estimated 是否进行犯罪估计
state_population 州人口数
violent_crime_total 暴力犯罪总数
murder_manslaughter 犯谋杀和过失杀人
rape_legacy 犯强奸罪(旧定义)
rape_revised 犯强奸罪(新定义)
robbery 犯抢劫罪
agg_assault 犯攻击性攻击
property_crime_total 财产犯罪总数
burglary 犯入室盗窃罪
larceny 犯盗窃罪
vehicle_theft 犯车辆盗窃罪

2.联合国犯罪与监禁数据
Country 国家
Region 所属州
Indicator 囚犯人群类别
Dimension 分类种类
Category 相关统计数据种类
Sex 性别
Age 年龄
Year 年份
VALUE 人数

导入数据集为crime_state

%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import seaborn as sns
myfont1 = FontProperties(fname = "simhei.ttf",size=18)
myfont2 = FontProperties(fname = "simhei.ttf",size=12)
crime_state = pd.read_excel(r'D:\dataset\crime_and_incarceration_by_state.xlsx')

在这里插入图片描述

二、数据预处理

1.缺失值处理

使用isnull()方法查看数据集有无缺失值,结果发现共有三处存在缺失值
在这里插入图片描述
首先是案件管辖权为联邦政府(即“FEDERAL”)的数据,由于在后续研究中,针对联邦政府仅使用“在押囚犯年终人数”这一字段数据,因此无需对其余空缺值做处理。

其次是纽约州2015年的数据出现大量缺失值,由于纽约州其余年份数据均完整,下面利用sklearn的KNN缺失值插补方法对数值型数据进行填充。

#KNN缺失值插补方法
from fancyimpute import KNN
newyork = crime_state[crime_state['jurisdiction']=='NEW YORK']
newyork['state_population'] = newyork['state_population'].interpolate()
# newyork['violent_crime_total'] = newyork['violent_crime_total'].interpolate()
newyork['murder_manslaughter'] = newyork['murder_manslaughter'].interpolate()
newyork['rape_legacy'] = newyork['rape_legacy'].interpolate()
newyork['rape_revised'] = newyork['rape_revised'].interpolate()
newyork['robbery'] = newyork['robbery'].interpolate()
newyork['agg_assault'] = newyork['agg_assault'].interpolate()
# newyork['property_crime_total'] = newyork['property_crime_total'].interpolate()
newyork['burglary'] = newyork['burglary'].interpolate()
newyork['larceny'] = newyork['larceny'].interpolate()
newyork['vehicle_theft'] = newyork['vehicle_theft'].interpolate()

最后是“犯强奸罪(新、旧定义)”两列出现大量缺失值。2012年1月6日,美国联邦调查局对强奸的定义作了修改,扩大了强奸一词的统计定义。正是由于这一变化,数据集统计的“犯强奸罪”字段有了新旧定义之分。
本文结合现实情况,决定2001年到2012年即强奸罪定义未修改之前,使用依据旧定义统计的数据;2013年到2016年即强奸罪定义修改之后,使用新定义下统计的数据。依据上述原则,对“犯强奸罪”字段进行整合,并将原数据集中的两列删除。

#处理”犯抢劫罪“字段
df1 = crime_state[crime_state['year']<2013]['rape_legacy']
df1 =pd.DataFrame(df1)
df1.rename(columns={'rape_legacy':'rape'},inplace=True)
df2 = crime_state[crime_state['year']>=2013]['rape_revised']
df2 =pd.DataFrame(df2)
df2.rename(columns={'rape_revised':'rape'},inplace=True)
df3 = pd.concat([df1,df2])
crime_state['rape']=df3
#计算犯罪总数
df4 = crime_state['violent_crime_total']+crime_state['property_crime_total']
crime_state['crime_total'] = df4

2.查看数据分布

选取“囚犯人口数”、“州人口数”、“暴力犯罪总数”、“财产犯罪总数”四个具有代表性的字段,对其数据分布进行查看。

from matplotlib.font_manager import FontProperties
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus']=False
myfont = FontProperties(fname = 'FangSong.TTF', size = 15)
x = crime_state["prisoner_count"]
fig,ax=plt.subplots(nrows=2,ncols=2,figsize=(8,8),dpi=1000)
plt.subplot(2, 2, 1)
plt.hist(x,bins = 8,color="g",alpha=0.5,edgecolor='black')
# 绘制x轴标题
plt.xlabel("囚犯人数",fontsize=8)
# 绘制y轴标题
plt.ylabel("频数",fontsize=8)
plt.title('囚犯人数直方图',fontsize=9)
plt.xticks(fontsize=8)

plt.subplot(2, 2, 2)
plt.hist(crime_state["state_population"],bins = 8,color="g",alpha=0.5,edgecolor='black')
# 绘制x轴标题
plt.xlabel("州人口数",fontsize=8)
# 绘制y轴标题
plt.ylabel("频数",fontsize=8)
plt.title('州人口数直方图',fontsize=9)
plt.xticks(fontsize=8)

plt.subplot(2, 2, 3)
crime_state.boxplot(column=["violent_crime_total"],showfliers=True,showmeans=True,notch=True)
plt.title('暴力犯罪总人数箱线图',fontsize=9)
plt.xticks(fontsize=8)

plt.subplot(2, 2, 4)
crime_state.boxplot(column=["property_crime_total"],showfliers=True,showmeans=True,notch=True)
plt.title('财产犯罪总人数箱线图',fontsize=9)
plt.xticks(fontsize=8)

plt.savefig(fname="pic.png",figsize=[8,8])
plt.show()

在这里插入图片描述
囚犯人数和州人口数采用直方图表示,暴力犯罪总数和财产犯罪总数选用箱线图呈现。以上字段数据分布均为左偏分布,州人口数与囚犯人数数据分布大致相同,这符合我们的一般认知。应当注意,四幅图中均有极端异常值的存在。极端异常值往往蕴含着更多的分析价值,在后续的分析中应当适当重视。

三、犯罪情况可视化分析

1.州别维度的可视化分析

美国共有50个州,数据集中有2001年到2016年各州的犯罪总人数,由于需要展现的维度较多,州的个数和年份也较多,因此该部分选择利用Pyecharts库绘制可交互的热力图,以期达到更清晰的可视化效果。
图例中的犯罪总人数即为暴力犯罪人数与财产犯罪人数之和。

crime_state_heat = crime_state.drop(crime_state[crime_state['jurisdiction']=='FEDERAL'].index)
ls=[]
for i in crime_state_heat['crime_total']:
    ls.append(i)
#获取X轴数据
xls=[]
for i in crime_state_heat['year'].drop_duplicates():
    xls.append(i)
print(xls)
#获取Y轴数据
yls=[]
for i in crime_state_heat['jurisdiction'].drop_duplicates():
    yls.append(i)
print(yls)
#获取热力图各坐标点对应的值
value = []
i=0
j=0
for k in range(len(ls)):
    a= ls[k]
    lsls = [i,j,a]
    value.append(lsls)
    j+=1
    if j>=50:
        i+=1
        j=0
from pyecharts import options as opts
from pyecharts.charts import HeatMap

c = (
    HeatMap(init_opts=opts.InitOpts(width='1000px',height='1100px'))
    .add_xaxis(xls)
    .add_yaxis(
        "犯罪总人数",
        yls,
        value=value,
        label_opts=opts.LabelOpts(is_show=True, position="inside"),
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="美国各州犯罪总人数(2001年-2016年)"),
        visualmap_opts=opts.VisualMapOpts(min_=min(ls),max_=max(ls),pos_top = "center",pos_right='1%')
    )
)
c.render_notebook()

在这里插入图片描述
根据热力图展现情况,总结两点结论:
1.各州内部情况对比。部分州年度犯罪总人数随时间变化并不大,变化率仅为1%。事实上,近年来全美犯罪人数出现下降趋势,治安情况向好。但同样存在犯罪总人数不减反增的情况如阿拉斯加州、南达科他州,这一趋势并不利于民众安全感的培养和社会治理环境的改善。
2.州与州之间情况对比。美国各州犯罪情况并不均衡,最大值约是最小值的150倍,相差悬殊。加利福尼亚州、得克萨斯州和佛罗里达州的犯罪人数突出,这些州具有共同特点是贫富差距较大、人口数量多、移民数量多;相比之下,其余大部分州的犯罪人数均处在较低水平。

2.类型维度的可视化分析

犯罪类型分为暴力犯罪和财产犯罪两大类。暴力犯罪又分为4种类型,分别为谋杀、抢劫、强奸和攻击;财产犯罪包括盗窃、入室盗窃、车辆盗窃3类。下面绘制主题河流图,该图不仅能够反映犯罪数量随时间的变化情况,还能展现各犯罪类型之间的数量关系。

x_data = ['盗窃','入室盗窃', '车辆盗窃','攻击','抢劫','强奸','谋杀']
y_data = [
    ['2001/1/1', 7069954.0, '盗窃'],
    ['2002/1/1', 7035671.0, '盗窃'],
    ['2003/1/1', 7008683.0, '盗窃'],
    ['2004/1/1', 6922547.0, '盗窃'],
    ['2005/1/1', 6768611.0, '盗窃'],
    ['2006/1/1', 6610455.0, '盗窃'],
    ['2007/1/1', 6574152.0, '盗窃'],
    ['2008/1/1', 6566248.0, '盗窃'],
    ['2009/1/1', 6318828.0, '盗窃'],
    ['2010/1/1', 6185087.0, '盗窃'],
    ['2011/1/1', 6129748.0, '盗窃'],
    ['2012/1/1', 6145299.0, '盗窃'],
    ['2013/1/1', 5994085.0, '盗窃'],
    ['2014/1/1', 5831598.0, '盗窃'],
    ['2015/1/1', 5685084.0, '盗窃'],
    ['2016/1/1', 5617746.0, '盗窃'],
    
    ['2001/1/1', 2111582.0, '入室盗窃'],
    ['2002/1/1', 2146082.0, '入室盗窃'],
    ['2003/1/1', 2150163.0, '入室盗窃'],
    ['2004/1/1', 2140500.0, '入室盗窃'],
    ['2005/1/1', 2151871.0, '入室盗窃'],
    ['2006/1/1', 2191158.0, '入室盗窃'],
    ['2007/1/1', 2186272.0, '入室盗窃'],
    ['2008/1/1', 2225099.0, '入室盗窃'],
    ['2009/1/1', 2199617.0, '入室盗窃'],
    ['2010/1/1', 2164226.0, '入室盗窃'],
    ['2011/1/1', 2181290.0, '入室盗窃'],
    ['2012/1/1', 2106413.0, '入室盗窃'],
    ['2013/1/1', 1928519.0, '入室盗窃'],
    ['2014/1/1', 1726340.0, '入室盗窃'],
    ['2015/1/1', 1577596.0, '入室盗窃'],
    ['2016/1/1', 1514044.0, '入室盗窃'],
    
    ['2001/1/1', 1220421.0, '车辆盗窃'],
    ['2002/1/1', 1237047.0, '车辆盗窃'],
    ['2003/1/1', 1251320.0, '车辆盗窃'],
    ['2004/1/1', 1229443.0, '车辆盗窃'],
    ['2005/1/1', 1228139.0, '车辆盗窃'],
    ['2006/1/1', 1190924.0, '车辆盗窃'],
    ['2007/1/1', 1092866.0, '车辆盗窃'],
    ['2008/1/1', 952594.0, '车辆盗窃'],
    ['2009/1/1', 790120.0, '车辆盗窃'],
    ['2010/1/1', 734510.0, '车辆盗窃'],
    ['2011/1/1', 712051.0, '车辆盗窃'],
    ['2012/1/1', 719523.0, '车辆盗窃'],
    ['2013/1/1', 697060.0, '车辆盗窃'],
    ['2014/1/1', 685744.0, '车辆盗窃'],
    ['2015/1/1', 704241.0, '车辆盗窃'],
    ['2016/1/1', 764363.0, '车辆盗窃'],
    
    ['2001/1/1', 904020.0, '攻击'],
    ['2002/1/1', 886445.0, '攻击'],
    ['2003/1/1', 854433.0, '攻击'],
    ['2004/1/1', 843413.0, '攻击'],
    ['2005/1/1', 858249.0, '攻击'],
    ['2006/1/1', 869507.0, '攻击'],
    ['2007/1/1', 862671.0, '攻击'],
    ['2008/1/1', 839976.0, '攻击'],
    ['2009/1/1', 809124.0, '攻击'],
    ['2010/1/1', 778462.0, '攻击'],
    ['2011/1/1', 749365.0, '攻击'],
    ['2012/1/1', 758504.0, '攻击'],
    ['2013/1/1', 722740.0, '攻击'],
    ['2014/1/1', 737166.0, '攻击'],
    ['2015/1/1', 760969.0, '攻击'],
    ['2016/1/1', 798915.0, '攻击'],
    
    ['2001/1/1', 419777.0, '抢劫'], 
    ['2002/1/1', 416972.0, '抢劫'], 
    ['2003/1/1', 410294.0, '抢劫'], 
    ['2004/1/1', 398268.0, '抢劫'], 
    ['2005/1/1', 413738.0, '抢劫'], 
    ['2006/1/1', 445417.0, '抢劫'], 
    ['2007/1/1', 443059.0, '抢劫'],
    ['2008/1/1', 439133.0, '抢劫'], 
    ['2009/1/1', 404338.0, '抢劫'],
    ['2010/1/1', 364764.0, '抢劫'], 
    ['2011/1/1', 350678.0, '抢劫'], 
    ['2012/1/1', 351014.0, '抢劫'], 
    ['2013/1/1', 341013.0, '抢劫'],
    ['2014/1/1', 322305.0, '抢劫'], 
    ['2015/1/1', 322874.0, '抢劫'], 
    ['2016/1/1', 329297.0, '抢劫'],
    
    ['2001/1/1', 90682, '强奸'],
    ['2002/1/1', 94973, '强奸'],
    ['2003/1/1', 93609, '强奸'],
    ['2004/1/1', 94867, '强奸'],
    ['2005/1/1', 94181, '强奸'],
    ['2006/1/1', 94287, '强奸'],
    ['2007/1/1', 91968, '强奸'],
    ['2008/1/1', 90564, '强奸'],
    ['2009/1/1', 89091, '强奸'],
    ['2010/1/1', 85406, '强奸'],
    ['2011/1/1', 84002, '强奸'],
    ['2012/1/1', 84905, '强奸'],
    ['2013/1/1', 113300, '强奸'],
    ['2014/1/1', 116173, '强奸'],
    ['2015/1/1', 123336, '强奸'],
    ['2016/1/1', 131881, '强奸'],
    
    ['2001/1/1', 15806, '谋杀'],
    ['2002/1/1', 15965, '谋杀'],
    ['2003/1/1', 16279, '谋杀'],
    ['2004/1/1', 15950, '谋杀'],
    ['2005/1/1', 16545, '谋杀'],
    ['2006/1/1', 17140, '谋杀'],
    ['2007/1/1', 16947, '谋杀'],
    ['2008/1/1', 16279, '谋杀'],
    ['2009/1/1', 15254, '谋杀'],
    ['2010/1/1', 14590, '谋杀'],
    ['2011/1/1', 14553, '谋杀'],
    ['2012/1/1', 14778, '谋杀'],
    ['2013/1/1', 14216, '谋杀'],
    ['2014/1/1', 14144, '谋杀'],
    ['2015/1/1', 15548, '谋杀'],
    ['2016/1/1', 17277, '谋杀']]
from pyecharts.charts import ThemeRiver
c=(
    ThemeRiver(init_opts=opts.InitOpts(width="900px", height="600px"))
    .add(
        series_name=x_data,
        data=y_data,
        singleaxis_opts=opts.SingleAxisOpts(
            pos_top="50", pos_bottom="50", type_="time"
        ),
    )
    .set_global_opts(
        tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="line"),
        title_opts=opts.TitleOpts(title="不同犯罪类型的数量",subtitle='主题河流图',item_gap=3,pos_top=30,pos_left='5%')
    )
)
c.render_notebook()

在这里插入图片描述
主题河流图中主要可视化因素是不同色块的垂直宽度。从整体来看,色块形状随着时间的推移呈现“收口”式,说明河流宽度在变窄,犯罪总数逐年减少。接下来,分析各犯罪类型数量发现,财产类型的犯罪要远远多于暴力类型的犯罪,其中又以盗窃罪为最,比其余六类犯罪数量总和还要多。暴力犯罪中,攻击罪数量最多,与财产类犯罪中车辆盗窃罪数量相当;之后依次为抢劫罪、强奸罪、谋杀罪。

由于暴力犯罪数量与财产犯罪数量差异较大,人眼对宽度变化不敏感,因此通过主题河流图只能看出数量较多的各财产犯罪的大致变化,很难得出数量较少的各暴力犯罪的数量变化趋势。为解决这一问题,下面将两大类犯罪分别进行可视化展示,首先是财产类型犯罪。

import pyecharts.options as opts
from pyecharts.charts import Line
from pyecharts.charts import Bar
from pyecharts.charts import Grid

x=['2001年', '2002年', '2003年', '2004年', '2005年', '2006年', '2007年', '2008年', '2009年', '2010年', '2011年', '2012年', '2013年', '2014年', '2015年', '2016年']
y1=[7069954.0, 7035671.0, 7008683.0, 6922547.0, 6768611.0, 6610455.0, 6574152.0, 6566248.0, 6318828.0, 6185087.0, 6129748.0, 6145299.0, 5994085.0, 5831598.0, 5685084.0, 5617746.0]
y2=[2111582.0, 2146082.0, 2150163.0, 2140500.0, 2151871.0, 2191158.0, 2186272.0, 2225099.0, 2199617.0, 2164226.0, 2181290.0, 2106413.0, 1928519.0, 1726340.0, 1577596.0, 1514044.0]
y3=[1220421.0, 1237047.0, 1251320.0, 1229443.0, 1228139.0, 1190924.0, 1092866.0, 952594.0, 790120.0, 734510.0, 712051.0, 719523.0, 697060.0, 685744.0, 704241.0, 764363.0]
y4=[904020.0, 886445.0, 854433.0, 843413.0, 858249.0, 869507.0, 862671.0, 839976.0, 809124.0, 778462.0, 749365.0, 758504.0, 722740.0, 737166.0, 760969.0, 798915.0]

bar=(
    Bar()
    .add_xaxis(xaxis_data=x)
    .add_yaxis(series_name="盗窃",y_axis=y1)
    .add_yaxis(series_name="入室盗窃",y_axis=y2)
    .add_yaxis(series_name="车辆盗窃",y_axis=y3)
    .set_global_opts(title_opts=opts.TitleOpts(title="财产犯罪数量变化"))
    .set_series_opts(label_opts=opts.LabelOpts(is_show=False),
        markpoint_opts=opts.MarkPointOpts(
            data=[
                opts.MarkPointItem(type_="max", name="最大值"),
            ]
        )
    )
)
line=(
    Line()
    .add_xaxis(xaxis_data=x)
    .add_yaxis(series_name="盗窃",y_axis=y1)
    .add_yaxis(series_name="入室盗窃",y_axis=y2)
    .add_yaxis(series_name="车辆盗窃",y_axis=y3)
    .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
)


bar.overlap(line)
grid = Grid(init_opts=opts.InitOpts(width='1500px',height='600px'))
grid.add(bar, opts.GridOpts(pos_left="5%", pos_right="20%"), is_control_axis_index=True)
grid.render_notebook()

@菜鸟驿站的程序猿
三类犯罪均有较为明显的下降趋势,分开来看可以得出如下结论:
1.盗窃类犯罪数量最大值出现在2001年,为7069950起。此后的十余年中,盗窃类犯罪保持平稳下降,减少率达20.5%。
2.入室盗窃类犯罪数量在2008年达到顶峰,为2225090起。2001年到2010年十年间,该罪数量变化不明显,始终保持在每年222万起上下。从2012年起,入室盗窃罪数量开始减少,降幅较为明显。与2001年相比,数量减少近4成。
3. 车辆盗窃类犯罪数量最大值出现在2003年,为1251320起。该类型数量变化分为三个阶段。一是2001年到2006年,在此期间犯罪数量在每年122万起上下;二是2006年到2014年的下降期,降低率达44.2%;三是2014年到2016年的抬头期,近年来车辆盗窃犯罪呈现增加趋势,2016年更是达到7年来的最高水平。

下面是暴力犯罪

import pyecharts.options as opts
from pyecharts.charts import Line
x=['2001年', '2002年', '2003年', '2004年', '2005年', '2006年', '2007年', '2008年', '2009年', '2010年', '2011年', '2012年', '2013年', '2014年', '2015年', '2016年']
y4=[904020.0, 886445.0, 854433.0, 843413.0, 858249.0, 869507.0, 862671.0, 839976.0, 809124.0, 778462.0, 749365.0, 758504.0, 722740.0, 737166.0, 760969.0, 798915.0]
y5=[419777.0, 416972.0, 410294.0, 398268.0, 413738.0, 445417.0, 443059.0, 439133.0, 404338.0, 364764.0, 350678.0, 351014.0, 341013.0, 322305.0, 322874.0, 329297.0]
y6=[90682.0, 94973.0, 93609.0, 94867.0, 94181.0, 94287.0, 91968.0, 90564.0, 89091.0, 85406.0, 84002.0, 84905.0, 113300.0, 116173.0, 123336.0, 131881.0]
y7=[15806.0, 15965.0, 16279.0, 15950.0, 16545.0, 17140.0, 16947.0, 16279.0, 15254.0, 14590.0, 14553.0, 14778.0, 14216.0, 14144.0, 15548.0, 17277.0]

line=(
    Line()
    .add_xaxis(xaxis_data=x)
    .add_yaxis(series_name="攻击",y_axis=y4)
    .set_series_opts(
        markarea_opts=opts.MarkAreaOpts(
            data=[
                opts.MarkAreaItem(name="攻击罪抬头期\强奸罪增长期", x=("2012年", "2016年")),
                opts.MarkAreaItem(name="抢劫罪高峰期", x=("2005年", "2009年")),
            ]
        )
    )
    .add_yaxis(series_name="抢劫",y_axis=y5)
    .add_yaxis(series_name="强奸",y_axis=y6)
    .add_yaxis(series_name="谋杀",y_axis=y7)
    .set_global_opts(title_opts=opts.TitleOpts(title="暴力犯罪数量变化"))

)
line.render_notebook()

在这里插入图片描述
在攻击罪和抢劫罪中,虽然两者数量都有增长时期,但最近年份的案发数量还是少于前期的,反观强奸罪和谋杀罪的数量变化趋势则截然相反。
强奸罪中,受到定义扩大的影响,2013年强奸罪的数量相比于2012年出现陡增,结束了8年来的下降趋势。自2013年起,强奸罪数量迎来增长期,截至2016年其数量已达到2001年的1.45倍;谋杀罪与抢劫罪趋势相似,2005年到2009年同样是谋杀罪的高峰期,此后逐年减少。在2014年之后,谋杀罪数量出现大幅增长,结合同时期攻击罪和强奸罪的数量增长变化分析,这一结果具有合理性。

3.性别维度的可视化分析

绘制了正负条形图进行可视化分析

df = pd.read_excel(r"D:\dataset\data_cts_prisons_and_prisoners.xlsx",sheet_name='Sheet1')
#右侧标签
right_labels=[]
for i in df[df['sex']=='Female']['num']:
    right_labels.append(i)
#左侧标签
left_labels=[]
for i in df[df['sex']=='Male']['num']:
    left_labels.append(i)
# 正负条形图
import matplotlib.pyplot as plt
import numpy as np
 
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
 

y_labels = ['2009年', '2010年', '2011年', '2012年', '2013年', '2014年','2015年','2016年','2017年','2018年','2019年']

a = np.array(right_labels)
b = np.array(left_labels)

fig,ax=plt.subplots(figsize=(15,10))
plt.xticks([])
plt.yticks(range(len(right_labels)), y_labels)
plt.title('囚犯性别分布情况(2009年-2019年)')
rect_a = plt.barh(range(len(a)), a, color='#ED7C30', height=0.5)
rect_b = plt.barh(range(len(b)), -b, color='#9DC3E7', height=0.5)

plt.legend((rect_b, rect_a), ("男", "女"), bbox_to_anchor=(0.5, 1.02), frameon=False,
           loc='upper center', ncol=2)

for x, y in enumerate(a):
    plt.text(0.8 * y, x, '%s' % y)
    # plt.ylim([0, str(y*2)])
for m, n in enumerate(b):
    plt.text(-n * 0.9, m, '%s' % n)

for item in ['top', 'right', 'left',"bottom"]:
    ax.spines[item].set_visible(False) #去掉边框
plt.show()

在这里插入图片描述
在数量上,男性囚犯数量要十倍于女性囚犯数量。一般认为女性缺乏强壮体力,在社会上处于从属地位,活动范围较小,故而女性犯罪率较低,囚犯数量也少于男性,这一点也符合绝大多数人的认知。

4.年龄维度的可视化分析

#成年囚犯数量变化
x = ['2004年','2005年','2006年','2007年','2008年','2009年', '2010年', '2011年', '2012年', '2013年', '2014年','2015年','2016年','2017年','2018年','2019年','2020年']
sns.set(style="whitegrid")
fig,ax=plt.subplots(figsize=(16,6))

plt.bar(x,y_ls,color="teal",width=0.65)
# x坐标轴的网格不使用刻度
ax.xaxis.grid(False)
# y坐标轴的网格使用主刻度
ax.yaxis.grid(True, which='major') 
# 添加数据标签
for a,b in zip(x,y_ls):
    ax.text(a, b+0.05," %i" % b, ha="center", va= "bottom",fontsize=12)
#去掉边框
for item in ['top', 'right', 'left']:
    ax.spines[item].set_visible(False) 
# 绘制标题
plt.title("成年囚犯数量变化柱形图(2004年-2020年)",fontproperties=myfont1)
plt.xticks(x, fontproperties=myfont2)
plt.show()
#青少年囚犯数量变化
x = ['2004年','2005年','2006年','2007年','2008年','2009年', '2010年', '2011年', '2012年', '2013年', '2014年','2015年','2016年','2017年','2018年','2019年','2020年']
sns.set(style="whitegrid")
fig,ax=plt.subplots(figsize=(16,6))

plt.bar(x,y1_ls,color="teal",width=0.65)
# x坐标轴的网格不使用刻度
ax.xaxis.grid(False)
# y坐标轴的网格使用主刻度
ax.yaxis.grid(True, which='major') 
# 添加数据标签
for a,b in zip(x,y1_ls):
    ax.text(a, b+0.05," %i" % b, ha="center", va= "bottom",fontsize=12)
#去掉边框
for item in ['top', 'right', 'left']:
    ax.spines[item].set_visible(False) 
# 绘制标题
plt.title("青少年囚犯数量变化柱形图(2004年-2020年)",fontproperties=myfont1)
plt.xticks(x, fontproperties=myfont2)
plt.show()

在这里插入图片描述
在这里插入图片描述
成年囚犯数量在2006年到2010年间处于高水平阶段,青少年囚犯数量变化趋势与成年具有相似之处。

四、监禁情况可视化分析

监禁率是指一个国家每10万人口中被监禁关押人口的数量,是一个国家监狱状况的重要指标。

1.美国国内监禁情况

根据监禁率定义,计算美国各州监禁率情况,按照年份分组求得全美年平均监禁率,将相关监禁率变化情况进行可视化展示。
在这里插入图片描述
16年来,美国监禁率整体形势为先上升后下降,于2007年达到最大值,近年来美国监禁率大有降低的趋势。
细化研究粒度,分析各州监禁率情况以及随时间变化情况。针对时间、州别、监禁率三个维度的变量,分别使用Timeline动态时间轴展示时间变化,地图热力图展示州别与监禁率变化。
在这里插入图片描述
监禁率与地理空间存在一定关系。东北部沿湖沿海地区以及犹他州、明尼苏达州监禁率较低;中等监禁率集中在五大湖地区以及向西延伸的各州;西部沿海地区、中南部地区以及阿拉斯加州是高监禁率地区。

2.美国与别国监禁情况比较

以2015年数据为例
在这里插入图片描述
色块大小代表该国监禁人数多少,色块深浅代表该国监禁率高低。
通过这个树图,可以清晰地看出,美国是当今世界上监禁人口最多、监禁率最高的国家。欧洲的俄罗斯、美洲的古巴监禁率在世界中也处在高水平。相比之下,亚洲各国平均监禁率不高,远远低于美洲、欧洲和非洲的平均监禁率。我国的监禁人数仅次于美国,但我国监禁率并不高,在世界范围内处于中低等水平。

分享到此结束啦~
在这里插入图片描述

  • 9
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值