Python替代R作图:使用pandas、matplotlib和seaborn进行高效数据可视化

时间:2025-04-22作者:admin分类:Python教程浏览:43评论:0

[id_8775086]

Python替代R作图:使用pandas、matplotlib和seaborn进行高效数据可视化

[id_[id_204358991]95894101]

大多数生物信息工作者会使用 R 来进行作图。R 语言具备丰富的 package ,并且有着友好的可视化界面,既方便又快捷,还易于上手。

因为工作需求,我一直借助 windows 来连接到 linux 平台的服务器以处理数据。通常会用 python 对文本数据进行前期处理,输出的结果都存于服务器中。若要作图,就需先将文件下载下来,然后再用 R 进行编辑,这让我感觉有些麻烦。

最开始我考虑是否存在 python 的替代方案。接着我发现,其实 python 本身就有专门用于绘图的模块,比如 matplotlib 等。

现在我借助 python 的 pandas 模块和 scipy 模块来处理数据,利用它的 matplotlib 模块和 seaborn 模块进行作图,这样就能直接在服务器上输出所需的图片。

话不多说,今天我先给大家介绍一下在 python 环境下 boxplot 的作图。大家可以了解一下它与 R 的差异,可能在操作上比 R 要复杂一些,希望大家能够谅解。

02

[id_1485302189]

python下我用的最多的应该是matplotlib

它自带有boxplot函数

这里先以经典的鸢尾花iris.csv数据来作图。

数据为5列150行矩阵,5列中包含4个特征:

萼片长宽(SepalLength、SepalWidth)

花瓣长宽(PetalLength、PetalWidth)

以及最后一列的花名,其中包含三种花,分别是 'Iris-setosa'、'Iris-versicolor'、'Iris-virginica'。

import 导入二维数组操作模块 pandas 并将其命名为 pd 。data = pd.read_csv('iris.csv') #导入数据print(data.head()) #打印数据前五行,结构如下:          SepalLength  SepalWidth 表示萼片宽度,PetalLength 表示花瓣长度,PetalWidth 表示花瓣宽度,Name 表示名称。0            3.5 是一个数值,1.4 是一个数值,0.2 是一个数值,Iris-setosa 是一个名称,5.1 也是一个数值。1            4.9 是一个数值,3.0 是另一个数值,1.4 是又一个数值,0.2 是再一个数值,而 Iris-setosa 是一个特定的名称。2            4.7 与 3.2 相比,4.7 更大;3.2 与 1.3 相比,3.2 更大;1.3 与 0.2 相比,1.3 更大;Iris-setosa 是特定的名称。3            Iris-setosa 这几个数值分别为 4.6、3.1、1.5、0.2 且包含 Iris-setosa 这一名称。4            5.0 这一数值,3.6 这个数字,1.4 该数值,0.2 此数字,以及 Iris-setosa 这个名称

先导入画图模块matplotlib,简单对一列作图

import matplotlib.pyplot as pltfig1, ax1 = plt.subplots()ax1.boxplot(data["SepalLength"])#boxplot 作图plt.show()

加上颜色

ax1.boxplot(data["SepalLength"],\    patch_artist=True, \  boxprops=dict(facecolor="darkred", color="darkred"))plt.show()

pandas 自带的 boxplot 能够依据 DataFram 数据结构直接进行作图。然而,我认为它的美观性存在不足,需要进行大量修改,正因如此,我基本上没有使用过它。

box=data.boxplot("SepalLength"grid 为 False ,且 patch_artist 为 True 。#加上颜色box 找到的对象(matplotlib.patches.Patch)中的第一个对象,将其填充颜色设置为"darkred")plt.show()

根据花名Name分组,比较4个特征:

bp_dict=data.boxplot(by="Name",grid = False,\  fontsize=10,rot=30,patch_artist=True,return_type='both')colors=["darkred","darkgreen","darkblue"]for row_key, (ax,row) in bp_dict.iteritems():#给每个box添加颜色    ax.set_xlabel('')    for i,box in enumerate(row['boxes']):        box.set_facecolor(colors[i])plt.show()

03

好用的boxplot

有一个很适用的模块叫 Seaborn,除了 matplotlib 和 pandas DataFrame 有 boxplot 外,Seaborn 也有 boxplot 函数。

Seaborn 实际上是以 matplotlib 为基础的。开发者进行了大量功能方面的封装。这样做使得作图变得更加容易。

鸢尾花四个特征的箱图

import seaborn as snssns.boxplot(data=data[:-1])#切片选择前四列数据plt.show()

小提琴图(内部默认为boxplot):

sns.violinplot(data=data[:-1])

内部填充观测值数据:

sns.violinplot(data=data[:-1],inner="stick")

04

进阶boxplot

这些分组 hue 可以通过更多分类特征的数据 tips 来介绍 。

tips = sns.load_dataset("tips") print(tips.head()) 总账单、小费、性别、吸烟者、日期、时间、人数16.99 是价格,1.01 是某个比例或数值,是女性,不是,在太阳下,吃晚餐,数量为 210.34,1.66,男性,否,太阳,晚餐,321.01 对应的是 3.50,性别为男性,没有,是在周日吃的晚餐,共 3 份。23.68 为 3.31 ,性别为男,无,晴天,晚餐,224.59 和 3.61 分别为两个数值,其中一个数值对应的是女性,并且没有特定情况,是在太阳下吃晚餐,这个情况出现了 4 次。

以 day 作为 X 轴,将 total_bill 展示出来,并且按照 smoker 进行分组。

ax = sns.boxplot(x="day", y="total_bill", hue="smoker",data=tips)plt.show()

分组后分裂模式的violinplot:

ax = sns.violinplot(x="day", y="total_bill", \  hue="smoker",data=tips,split=True)plt.show()

在boxplot上添加观测值:

ax = sns.boxplot(x="day", y="total_bill", hue="smoker",data=tips)ax = sns.stripplot(x="day", y="total_bill",\  hue="smoker",dodge=True, data=tips, \  color=".25",edgecolor="black",linewidth=0.75,palette="muted")
#只显示一个legendax 获取到图例的句柄和标签,分别赋值给 handles 和 labels 。ax 为图表的轴对象,它的 legend 方法用于添加图例。handles[0:2]表示获取前两个图形对象的句柄,labels[0:2]表示获取对应的前两个标签。通过调用 ax.legend(handles[0:2], labels[0:2]),可以在图表中添加由前两个图形对象及其对应的标签组成的图例。 title="smoker"此句有“loc=1”“framealpha=0.5”“bbox_to_anchor=(1, 0.98)”等内容,分别进行描述。此句存在“loc=1”这一情况,还有“framealpha=0.5”的设定,同时具备“bbox_to_anchor=(1, 0.98)”的特点。plt.show()

计算显著性以及加上显著线:

这里使用statannot模块,目前还不能通过pip安装。

要到 github 上去下载 statannot 的安装包,接着将其解压到你的 python 模块目录中,然后利用 setup.py 进行安装,最后导入注释模块。

python setup.py install from statannot import add_stat_annotation

使用t-test检验,加上显著线以及p-value

ax = sns.boxplot(x="day", y="total_bill", hue="smoker",data=tips)
add_stat_annotation(ax, data=tips, x="day", y="total_bill", \ hue="smoker", box_pairs=[(("Thur", "No"), ("Fri", "No")), (("Sat", "Yes"), ("Sat", "No")), (("Sun", "No"), ("Thur", "Yes")) ], test='t-test_ind', \ text_format='full', loc='inside', line_offset_to_box=0.2, \ line_offset=0.1, line_height=0.05, \ text_offset=8, verbose=2)handles, labels = ax.get_legend_handles_labels()ax.legend(handles[0:2], labels[0:2],\ title="smoker",loc=1,framealpha=0.5,bbox_to_anchor=(1, 0.88))

05

boxplot延伸

分组云雨图Raincloud:

import ptitprince as ptfig, ax = plt.subplots()pt.RainCloud(x="day", y="total_bill", hue="smoker",palette='muted',             bw = 0.2,width_viol = 0.7,alpha = 0.65,             orient = 'h',move=0.2,data=tips,ax=ax)handles, labels = ax.get_legend_handles_labels()ax.legend(handles[0:2], labels[0:2],\  title="smoker",loc=1,framealpha=0.5,bbox_to_anchor=(1, 0.98))plt.show()

结语

很多时候,感觉使用 Python 作图不如 R 方便。然而,现在 Stack Overflow 上关于 Python 作图、Pandas 数据变换等相关问题的帖子呈指数增加。正因如此,使用 Python 作图的时间成本大大降低了。使用 Python 进行文本处理之后,再结合 Pandas 的使用,使得许多 Python 的作图方法变得像 R 那样容易,而且出图效果很漂亮,对我而言,基本上能够满足科技论文作图的需求。

整个过程先是用 Python 编写文件处理脚本,接着用 Pandas 处理数据,再用 Scipy 进行科学计算,之后用 Matplotlib 和 Seaborn 进行可视化处理,这可以说是一站式地解决了数据分析问题,对于我而言,是非常流畅的用户体验。

我认为还是有必要再掌握一下 R 的作图。因为身边的同学都在用这个,大家一起交流进步的话,能够成长得更快一些。

今天关于 Python 中 boxplot 画法的简单介绍到此结束。若有问题,可在我们的公众号留言。之后我会整理一些 Python 其他的画图方法,希望大家持续关注我们。

你可能想看:

猜你喜欢