Python数据可视化的例子——箱线图(box)

箱线图是另一种体现数据分布的图形,通过该图可以得知数据的下须值(Q1-1.5IQR)、下四分位数(Q1)、中位数(Q2)、均值、上四分位数(Q3)和上须值(Q3+1.5IQR),更重要的是,箱线图还可以发现数据中的异常点
箱线图的绘制仍然可以通过matplotlib模块、pandas模块和seaborn模块完成,下面将一一介绍各模块绘制条形图的过程。

1.matplotlib模块

首先介绍一下matplotlib模块中绘制箱线图的boxplot函数,有关该函数的语法和参数含义如下:

plt.boxplot(x, notch=None, sym=None, vert=None,
            whis=None, positions=None, widths=None,
            patch_artist=None, meanline=None, showmeans=None,
            showcaps=None, showbox=None, showfliers=None,
            boxprops=None, labels=None, flierprops=None,
            medianprops=None, meanprops=None,
            capprops=None, whiskerprops=None)
  • x:指定要绘制箱线图的数据。
  • notch:是否以凹口的形式展现箱线图,默认非凹口。
  • sym:指定异常点的形状,默认为+号显示。
  • vert:是否需要将箱线图垂直摆放,默认垂直摆放。
  • whis:指定上下须与上下四分位的距离,默认为1.5倍的四分位差。
  • positions:指定箱线图的位置,默认为[0,1,2…]。
  • widths:指定箱线图的宽度,默认为0.5。
  • patch_artist:bool类型参数,是否填充箱体的颜色;默认为False。
  • meanline:bool类型参数,是否用线的形式表示均值,默认为False。
  • showmeans:bool类型参数,是否显示均值,默认为False。
  • showcaps:bool类型参数,是否显示箱线图顶端和末端的两条线(即上下须),默认为True。
  • showbox:bool类型参数,是否显示箱线图的箱体,默认为True。
  • showfliers:是否显示异常值,默认为True。
  • boxprops:设置箱体的属性,如边框色,填充色等。
  • labels:为箱线图添加标签,类似于图例的作用。
  • filerprops:设置异常值的属性,如异常点的形状、大小、填充色等。
  • medianprops:设置中位数的属性,如线的类型、粗细等。
  • meanprops:设置均值的属性,如点的大小、颜色等。
  • capprops:设置箱线图顶端和末端线条的属性,如颜色、粗细等。
  • whiskerprops:设置须的属性,如颜色、粗细、线的类型等。
    现在,以某平台二手房数据为例,运用箱线图探究其二手房单价的分布情况:
    在这里插入图片描述
    具体代码如下:
import pandas as pd
import matplotlib.pyplot as plt

# 读入数据
Sec_Buildings = pd.read_excel(r'不同行政区域的二手房信息.xlsx')
#设置绘图风格
plt.style.use('ggplot')
#处理中文乱码
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
#坐标轴负号的处理
plt.rcParams['axes.unicode_minus']=False

# 绘制箱线图
plt.boxplot(x = Sec_Buildings.price_unit, # 指定绘图数据
            patch_artist=True, # 要求用自定义颜色填充盒形图,默认白色填充
            showmeans=True, # 以点的形式显示均值
            boxprops = {'color':'black','facecolor':'steelblue'}, # 设置箱体属性,如边框色和填充色
            # 设置异常点属性,如点的形状、填充色和点的大小
            flierprops = {'marker':'o','markerfacecolor':'red', 'markersize':3},
            # 设置均值点的属性,如点的形状、填充色和点的大小
            meanprops = {'marker':'D','markerfacecolor':'blue', 'markersize':4},
            # 设置中位数线的属性,如线的类型和颜色
            medianprops = {'linestyle':'--','color':'orange'},
            labels = [''] # 删除x轴的刻度标签,否则图形显示刻度标签为1
           )
# 添加图形标题
plt.title('二手房单价分布的箱线图')
# 显示图形
plt.show()

在这里插入图片描述
如上图所示,图中的上下两条横线代表上下须、箱体的上下两条横线代表上下四分位数、箱体中的虚线代表中位数、箱体中的点则为均值、上下须两端的点代表异常值。通过图中均值和中位数的对比就可以得知数据微微右偏(判断标准:如果数据近似正态分布,则众数=中位数=均值;如果数据右偏,则众数<中位数<均值;如果数值左偏,则众数>中位数>均值)。 如上绘制的是二手房整体单价的箱线图,这样的箱线图可能并不常见,更多的是分组箱线图,即二手房的单价按照其他分组变量(如行政区域、楼层、朝向等)进行对比分析。下面继续使用matplotlib模块对二手房的单价绘制分组箱线图,代码如下:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 读入数据
Sec_Buildings = pd.read_excel(r'不同行政区域的二手房信息.xlsx')
#设置绘图风格
plt.style.use('ggplot')
#处理中文乱码
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
#坐标轴负号的处理
plt.rcParams['axes.unicode_minus']=False

# 二手房在各行政区域的平均单价
group_region = Sec_Buildings.groupby('region')
avg_price = group_region.aggregate({'price_unit':np.mean}).sort_values('price_unit', ascending = False)
# print(avg_price)
# print(avg_price.index)
# 通过循环,将不同行政区域的二手房存储到列表中
region_price = []
for region in avg_price.index:
    region_price.append(Sec_Buildings.price_unit[Sec_Buildings.region == region])
# 绘制分组箱线图
plt.boxplot(x = region_price,  # 指定绘图数据
            patch_artist=True,  # 要求用自定义颜色填充盒形图,默认白色填充
            labels = avg_price.index, # 添加x轴的刻度标签
            showmeans=True,  # 以点的形式显示均值
            boxprops = {'color':'black', 'facecolor':'steelblue'},  # 设置箱体属性,如边框色和填充色
            flierprops = {'marker':'o','markerfacecolor':'red', 'markersize':3},  # 设置异常点属性,如点的形状、填充色和点的大小
            meanprops = {'marker':'D','markerfacecolor':'blue', 'markersize':4},  # 设置均值点的属性,如点的形状、填充色和点的大小
            medianprops = {'linestyle':'--','color':'orange'}  # 设置中位数线的属性,如线的类型和颜色
           )
# 添加y轴标签
plt.ylabel('单价(元)')
# 添加标题
plt.title('不同行政区域的二手房单价对比')
# 显示图形
plt.show()

print(avg_price)
print(avg_price.index)

          price_unit
region              
静安      92920.466667
黄浦      88764.663220
徐汇      75758.458631
长宁      70295.307244
虹口      67264.039347
杨浦      65549.499725
闸北      64985.371483
普陀      60977.385854
浦东      60513.039575
闵行      53667.534058
宝山      49971.513572
松江      41779.174870
嘉定      41596.720917
青浦      39349.514793
奉贤      30576.963314
金山      22521.181818
崇明      19181.250000
Index(['静安', '黄浦', '徐汇', '长宁', '虹口', '杨浦', '闸北', '普陀', '浦东', '闵行', '宝山', '松江',
       '嘉定', '青浦', '奉贤', '金山', '崇明'],
      dtype='object', name='region')

在这里插入图片描述
应用matplotlib模块绘制如上所示的分组箱线图会相对烦琐一些,由于boxplot函数每次只能绘制一个箱线图,为了能够实现多个箱线图的绘制,对数据稍微做了一些变动,即将每个行政区域下的二手房单价汇总到一个列表中,然后基于这个大列表应用boxplot函数。在绘图过程中,首先做了一个“手脚”,那就是统计各行政区域二手房的平均单价,并降序排序,这样做的目的就是让分组箱线图能够降序呈现。
虽然pandas模块中的plot方法可以绘制分组箱线图,但是该方法是基于数据框执行的,并且数据框的每一列对应一个箱线图。对于二手房数据集来说,应用plot方法绘制分组箱线图不太合适,因为每一个行政区的二手房数量不一致,将导致无法重构一个新的数据框用于绘图。

2.seaborn模块

如果读者觉得matplotlib模块绘制分组箱线图比较麻烦,可以使用seaborn模块中的boxplot函数。下面不妨先了解一下该函数的参数含义:

sns.boxplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None,
       		orient=None, color=None, palette=None, saturation=0.75, width=0.8,
       		dodge=True, fliersize=5, linewidth=None, whis=1.5, notch=False, ax=None, **kwargs)
  • x:指定箱线图的x轴数据。
  • y:指定箱线图的y轴数据。
  • hue:指定分组变量。
  • data:指定用于绘图的数据集。
  • order:传递一个字符串列表,用于分类变量的排序。
  • hue_order:传递一个字符串列表,用于分类变量hue值的排序。
  • orient:指定箱线图的呈现方向,默认为垂直方向。
  • color:指定所有箱线图的填充色。
  • palette:指定hue变量的区分色。
  • saturation:指定颜色的透明度。
  • width:指定箱线图的宽度。
  • dodge:bool类型的参数,当使用hue参数时,是否绘制水平交错的箱线图,默认为True。
  • fliersize:指定异常值点的大小。
  • linewidth:指定箱体边框的宽度。
  • whis:指定上下须与上下四分位的距离,默认为1.5倍的四分位差。
  • notch:bool类型的参数,是否绘制凹口箱线图,默认为False。
  • ax:指定子图的位置。
  • **kwargs:关键字参数,可以调用plt.boxplot函数中的其他参数。
    这里仍以上海二手房数据为例,应用seaborn模块中的boxplot函数绘制分组箱线图,详细代码如下:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
# 读入数据
Sec_Buildings = pd.read_excel(r'不同行政区域的二手房信息.xlsx')
#设置绘图风格
plt.style.use('ggplot')
#处理中文乱码
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
#坐标轴负号的处理
plt.rcParams['axes.unicode_minus']=False

# 二手房在各行政区域的平均单价
group_region = Sec_Buildings.groupby('region')
avg_price = group_region.aggregate({'price_unit':np.mean}).sort_values('price_unit', ascending = False)
# 通过循环,将不同行政区域的二手房存储到列表中
region_price = []
for region in avg_price.index:
    region_price.append(Sec_Buildings.price_unit[Sec_Buildings.region == region])
# 绘制分组箱线图
sns.boxplot(x = 'region',  #箱线图的x轴数据
            y = 'price_unit',  #箱线图的y轴数据
            data = Sec_Buildings,  #用于绘图的数据集
            order = avg_price.index,  #传递一个字符串列表,用于分类变量的排序
            showmeans=True,  #以点的形式显示均值
            color = 'steelblue',  #指定所有箱线图的填充色
            flierprops = {'marker':'o','markerfacecolor':'red', 'markersize':3},  # 设置异常点属性,如点的形状、填充色和点的大小
            meanprops = {'marker':'D','markerfacecolor':'blue', 'markersize':4},  # 设置均值点的属性,如点的形状、填充色和点的大小
            medianprops = {'linestyle':'--','color':'orange'}  # 设置中位数线的属性,如线的类型和颜色
           )
# 更改x轴和y轴标签
plt.xlabel('区域')
plt.ylabel('单价(元)')
# 添加标题
plt.title('不同行政区域的二手房单价对比')
#控制横纵坐标的值域
plt.axis([-1,17,0,210000])
# 显示图形
plt.show()

不加控制横纵坐标的值域的图为:
在这里插入图片描述
加了控制横纵坐标的值域的图为:
在这里插入图片描述
通过如上代码,同样可以得到完全一致的分组箱线图。这里建议读者不要直接学习和使用pandas模块和seaborn模块绘制统计图形,而是先把matplotlib模块摸透,因为Python的核心绘图模块是matplotlib

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值