Python数据可视化:箱线图多种库画法


Posted in Python onNovember 06, 2019

概念

箱线图通过数据的四分位数来展示数据的分布情况。例如:数据的中心位置,数据间的离散程度,是否有异常值等。

把数据从小到大进行排列并等分成四份,第一分位数(Q1),第二分位数(Q2)和第三分位数(Q3)分别为数据的第25%,50%和75%的数字。

Python数据可视化:箱线图多种库画法

四分位间距(Interquartilerange(IQR))=上分位数(upper quartile)-下分位数(lower quartile)

箱线图分为两部分,分别是箱(box)和须(whisker)。箱(box)用来表示从第一分位到第三分位的数据,须(whisker)用来表示数据的范围。

箱线图从上到下各横线分别表示:数据上限(通常是Q3+1.5IQR),第三分位数(Q3),第二分位数(中位数),第一分位数(Q1),数据下限(通常是Q1-1.5IQR)。有时还有一些圆点,位于数据上下限之外,表示异常值(outliers)。

(注:如果数据上下限特别大,那么whisker将显示数据的最大值和最小值。)

Python数据可视化:箱线图多种库画法

案例

1. 使用pandas自带的函数

使用pandas里的dataframe数据结构存放待显示的数据。如果希望显示的各个数据列表中,数据长度不一致,可以先用Series函数转换为Series数据,再存储到dataframe中,对应index的value值若不存在则为NaN。

下面我们随机生成4组数据,看看他们的箱线图。

【代码】

import numpy as np 
import pandas as pd 
from matplotlib import pyplot as plt 
def list_generator(mean, dis, number): # 封装一下这个函数,用来后面生成数据 
 return np.random.normal(mean, dis * dis, number) # normal分布,输入的参数是均值、标准差以及生成的数量 
# 我们生成四组数据用来做实验,数据量分别为70-100 
y1 = list_generator(0.8531, 0.0956, 70) 
y2 = list_generator(0.8631, 0.0656, 80) 
y3 = list_generator(0.8731, 0.1056, 90) 
y4 = list_generator(0.8831, 0.0756, 100) 
# 如果数据大小不一,记得需要下面语句,把数组变为series 
y1 = pd.Series(np.array(y1)) 
y2 = pd.Series(np.array(y2)) 
y3 = pd.Series(np.array(y3)) 
y4 = pd.Series(np.array(y4)) 
data = pd.DataFrame({"1": y1, "2": y2, "3": y3, "4": y4, }) 
data.boxplot() # 这里,pandas自己有处理的过程,很方便哦。 
plt.ylabel("ylabel") 
plt.xlabel("xlabel") # 我们设置横纵坐标的标题。 
plt.show()

【效果】

Python数据可视化:箱线图多种库画法

上面的箱线图很简单,给出数据后,几行代码就能生成,不过这是简单的箱线图。下面再看看稍微复杂点的。

2. 使用matplotlib库画箱线图

我们上面介绍了使用pandas画箱线图,几句命令就可以了。但是稍微复杂点的可以使用matplotlib库。matplotlib代码稍微复杂点,但是很灵活。细心点同学会发现pandas里面的画图也是基于此库的,下面给你看看pandas里面的源码:

Python数据可视化:箱线图多种库画法

通过源码可以看到pandas内部也是通过调用matplotlib来画图的。那下面我们自己实现用matplotlib画箱线图。

我们简单模拟一下,男女生从20岁,30岁的花费对比图,使用箱线图来可视化一下。

【代码】

import numpy as np 
import matplotlib.pyplot as plt 
fig, ax = plt.subplots() # 子图 
def list_generator(mean, dis, number): # 封装一下这个函数,用来后面生成数据 
 return np.random.normal(mean, dis * dis, number) # normal分布,输入的参数是均值、标准差以及生成的数量 
 
# 我们生成四组数据用来做实验,数据量分别为70-100 
# 分别代表男生、女生在20岁和30岁的花费分布 
girl20 = list_generator(1000, 29.2, 70) 
boy20 = list_generator(800, 11.5, 80) 
girl30 = list_generator(3000, 25.1056, 90) 
boy30 = list_generator(1000, 19.0756, 100) 
 
data=[girl20,boy20,girl30,boy30,] 
ax.boxplot(data) 
ax.set_xticklabels(["girl20", "boy20", "girl30", "boy30",]) # 设置x轴刻度标签 
plt.show()

【效果】

Python数据可视化:箱线图多种库画法

从上面随机模拟,看出来男生花费赶不上女生吧,尤其是30岁以后,女生摔男生一大截啊。(模拟数据,请勿当真)

仔细看上面的图,感觉还是不太好,既然男女生对比,那是不是要分组,男女生放一块,然后再根据年龄段比较,这样比较才直观。

那我们就稍微改动上面一点点代码,实现男女生箱线图挨得近一点。

【代码】

import numpy as np 
import matplotlib.pyplot as plt 
fig, ax = plt.subplots() # 子图 
def list_generator(mean, dis, number): # 封装一下这个函数,用来后面生成数据 
 return np.random.normal(mean, dis * dis, number) # normal分布,输入的参数是均值、标准差以及生成的数量 
 
# 我们生成四组数据用来做实验,数据量分别为70-100 
# 分别代表男生、女生在20岁和30岁的花费分布 
girl20 = list_generator(1000, 29.2, 70) 
boy20 = list_generator(800, 11.5, 80) 
girl30 = list_generator(3000, 25.1056, 90) 
boy30 = list_generator(1000, 19.0756, 100) 
 
 
data=[girl20,boy20,girl30,boy30,] 
# 用positions参数设置各箱线图的位置 
ax.boxplot(data,positions=[0, 0.6, 3, 3.7,])# 就是后面加了位置 
ax.set_xticklabels(["girl20", "boy20", "girl30", "boy30",]) # 设置x轴刻度标签 
plt.show()

【效果】

Python数据可视化:箱线图多种库画法

这样看一下,是不是男女生根据年龄段分组了呢,稍微比上面好看些,也直观一些。这样既能看出年龄段的对比,又能看出男女生的对比。

同样,如果想要箱线图旋转90°,那么也是在在 boxplot命令里加上参数 vert=False即可。如果想要更多设置,可以基于 boxplot函数参数进行修改,其函数定义如下:

boxplot(self, x, notch=None, sym=None, vert=None, whis=None, 
 positions=None, widths=None, patch_artist=None, 
 bootstrap=None, usermedians=None, conf_intervals=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, 
 manage_xticks=True, autorange=False, zorder=None)

3. 使用seaborn库和matplotlib来画箱线图

Seaborn是基于matplotlib的Python可视化库。 它提供了一个高级界面来绘制有吸引力的统计图形。Seaborn其实是在matplotlib的基础上进行了更高级的API封装,从而使得作图更加容易,不需要经过大量的调整就能使你的图变得精致。但应强调的是,应该把Seaborn视为matplotlib的补充,而不是替代物。

函数定义:

boxplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None, 
 orient=None, color=None, palette=None, saturation=.75, 
 width=.8, dodge=True, fliersize=5, linewidth=None, 
 whis=1.5, notch=False, ax=None, **kwargs)

【参数讲解】 x,y:dataframe中的列名(str)或者矢量数据

  •  data:dataframe或者数组
  • palette:调色板,控制图像的色调
  • hue(str):dataframe的列名,按照列名中的值分类形成分类的条形图
  • order, hue_order (lists of strings):用于控制条形图的顺序
  • orient:"v"|"h" 用于控制图像使水平还是竖直显示(这通常是从输入变量的dtype推断出来的,此参数一般当不传入x、y,只传入data的时候使用)
  • fliersize:float,用于指示离群值观察的标记大小
  • whis:确定离群值的上下界(IQR超过低和高四分位数的比例),此范围之外的点将被识别为异常值。IQR指的是上下四分位的差值。
  • width:float,控制箱型图的宽度

我们还是基于上面男女花费案例来说,不过这里我们把数据进行了整理,做成了数据框dataframe。

【包含的库】

import pandas as pd 
import numpy as np 
import seaborn as sns 
import matplotlib.pyplot as plt 
# plt.rc("font", family="SimHei", size="15") 避免中文乱码,可不用

【代码第一部分】数据生成

def list_generator(mean, dis, number): # 封装一下这个函数,用来后面生成数据 
 return np.random.normal(mean, dis * dis, number) # normal分布,输入的参数是均值、标准差以及生成的数量 
 
# 我们生成四组数据用来做实验,数据量分别为70-100 
# 分别代表男生、女生在20岁和30岁的花费分布 
# 构造数据库DataFrame 
num = 100 # 每组100个样本 
girl20 = list_generator(1000, 29.2, num) 
boy20 = list_generator(800, 11.5, num) 
girl30 = list_generator(3000, 25.1056, num) 
boy30 = list_generator(1000, 19.0756, num) 
girl_sex = ['female' for _ in range(num)] 
boy_sex = ['male' for _ in range(num)] 
age20 = [20 for _ in range(num)] 
age30 = [30 for _ in range(num)] 
 
girl_d1 = pd.DataFrame({'cost': girl20, 'sex': girl_sex, 'age': age20}) 
boy_d1 = pd.DataFrame({'cost': boy20, 'sex': boy_sex, 'age': age20}) 
girl_d2 = pd.DataFrame({'cost': girl30, 'sex': girl_sex, 'age': age30}) 
boy_d2 = pd.DataFrame({'cost': boy30, 'sex': boy_sex, 'age': age30}) 
data = pd.concat([girl_d1, boy_d1, girl_d2, boy_d2]) 
 
print(data.head())

数据长啥样?下面是给出的数据框前面的部分,一共400个样本,分性别和年龄。

Python数据可视化:箱线图多种库画法

【代码第二部分】使用seaborn库画图

简单看看所有数据的分布情况:

sns.boxplot(x="age", y="cost", data=data, hue="sex", width=0.5, linewidth=1.0, palette="Set3")
Python数据可视化:箱线图多种库画法

根据性别分组:

sns.boxplot(x="age", y="cost", data=data, hue="sex", width=0.5, linewidth=1.0, palette="Set3")
Python数据可视化:箱线图多种库画法

根据年龄分组:

sns.boxplot(x="sex", y="cost", data=data, hue="age", width=0.5, linewidth=1.0, palette="Set3")
Python数据可视化:箱线图多种库画法

上面这些是seaborn库的简单使用,可以通过年龄看男女花费比较,也可以根据性别看不同年龄段的花费比较,还是比较直观的。当然除此之外还有很多其他的炫技,大家可以自己尝试。

总结

从上面来看,虽然我们是采用不同方法来画箱线图,但是最基本的都是调用matplotlib库,这里面pandas是最简单的箱线图可视化,但是不灵活。而matplotlib虽然灵活,但是需要慢慢调,而且复杂。相比之下seaborn更加酷炫,而且图还更好看。上面例子都是本人亲测,一个个对比,原创文章,大家如果有其他问题可以留言讨论。

Python 相关文章推荐
python缩进区别分析
Feb 15 Python
python生成日历实例解析
Aug 21 Python
推荐11个实用Python库
Jan 23 Python
浅谈Python中数据解析
May 05 Python
Python中import导入上一级目录模块及循环import问题的解决
Jun 04 Python
Python利用ElementTree模块处理XML的方法详解
Aug 31 Python
TensorFlow实现创建分类器
Feb 06 Python
python入门:这篇文章带你直接学会python
Sep 14 Python
Django restframework 源码分析之认证详解
Feb 22 Python
python中break、continue 、exit() 、pass终止循环的区别详解
Jul 08 Python
Flask框架搭建虚拟环境的步骤分析
Dec 21 Python
Python3 搭建Qt5 环境的方法示例
Jul 16 Python
使用Python完成15位18位身份证的互转功能
Nov 06 #Python
python3.8 微信发送服务器监控报警消息代码实现
Nov 05 #Python
python SVD压缩图像的实现代码
Nov 05 #Python
Django REST框架创建一个简单的Api实例讲解
Nov 05 #Python
python中for循环变量作用域及用法详解
Nov 05 #Python
Python对Excel按列值筛选并拆分表格到多个文件的代码
Nov 05 #Python
pytorch torch.expand和torch.repeat的区别详解
Nov 05 #Python
You might like
PHP中通过HTTP_USER_AGENT判断是否为手机移动终端的函数代码
2013/02/14 PHP
ThinkPHP中U方法的使用浅析
2014/06/13 PHP
PHP生成图片缩略图类示例
2017/01/12 PHP
漂亮的提示信息(带箭头)
2007/03/21 Javascript
再谈javascript 动态添加样式规则 W3C校检
2009/12/25 Javascript
JavaScript 拾漏补遗
2009/12/27 Javascript
javascript 解决表单仍然提交即使监听处理函数返回false
2010/03/14 Javascript
js 异步处理进度条
2010/04/01 Javascript
js页面跳转的问题(跳转到父页面、最外层页面、本页面)
2013/08/14 Javascript
jQuery实现密保互斥问题解决方案
2013/08/16 Javascript
Javascript中的arguments与重载介绍
2015/03/15 Javascript
bootstrap模态框示例代码分享
2017/05/17 Javascript
Vue子组件向父组件通信与父组件调用子组件中的方法
2018/06/22 Javascript
详解为什么Vue中不要用index作为key(diff算法)
2020/04/04 Javascript
微信小程序实现身份证取景框拍摄
2020/09/09 Javascript
ant design的table组件实现全选功能以及自定义分页
2020/11/17 Javascript
[14:25]教你分分钟做大人:主宰(HEROS)
2014/12/08 DOTA
[05:49]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS 选手采访
2021/03/11 DOTA
Python中的localtime()方法使用详解
2015/05/22 Python
在Python中操作时间之tzset()方法的使用教程
2015/05/22 Python
python 查找字符串是否存在实例详解
2017/01/20 Python
python数据抓取分析的示例代码(python + mongodb)
2017/12/25 Python
python删除某个字符
2018/03/19 Python
解决Python plt.savefig 保存图片时一片空白的问题
2019/01/10 Python
python 通过可变参数计算n个数的乘积方法
2019/06/13 Python
python二维码操作:对QRCode和MyQR入门详解
2019/06/24 Python
在python3.9下如何安装scrapy的方法
2021/02/03 Python
Harrods美国:英国最大的百货公司
2018/11/04 全球购物
实习自我鉴定模板
2013/09/28 职场文书
国际会议邀请函范文
2014/01/16 职场文书
音乐专业自荐信
2014/02/07 职场文书
大学新学期计划书
2014/04/28 职场文书
大学生求职计划书
2014/04/30 职场文书
旷课检讨书范文
2015/01/27 职场文书
行政经理岗位职责
2015/04/15 职场文书
Python中tkinter的用户登录管理的实现
2021/04/22 Python