生信分析中,画箱线图是常见的需求。最早图简单用seaborn画箱线图。最近下定决心学matplotlib了,所以还是给出matplotlib版本的尝试,但是部分用法还是稚嫩,可能用了笨办法,欢迎大家指正。
箱线图的定义和含义这里就略过了。
前期数据处理部分也略过,画3张子图,3个Dataframe形式如下表所示,表中数据为AF(等位基因频率)。由于两组样本数不统一,所以有缺省项,但这并不影响箱线图绘制。
import pandas as pd import numpy as np import matplotlib.pyplot as plt#导入matplotlib from scipy import stats#用来计算非参数检验P_value fig=plt.figure(figsize=(20,10))#初始化图片 i=1 #该变量用来迭代3图片,每次for循环会+1 d={1:'fig1',2:'fig2',3:'fig3'} #3张子图的名字 for df in [fig1_data,fig2_data,fig3_data]:#对三个df进行循环 ax=fig.add_subplot(1,3,i)#一共一排,一排三张图,目前是第i张。 pvalue=stats.mannwhitneyu(df['new'],df['old'],alternative='two-sided')[1] #对新旧数据进行非参数检验-秩和检验,得空写写mannwhitneyu和Wilcoxon的区别。 #首先df['old']或者df['new']取到某列array,然后dropna()去除该array中的空值。labels是横轴上每个小箱的标签。widths是箱宽。patch_artist为是否填充箱体的颜色,如不要默认设置,想自己设置,则该项选True。boxprops定义box的参数。flierprops定义离群值的参数。medianprops定义中位线的参数。 plt.boxplot([df['old'].dropna(),df['new'].dropna()],labels=['old','new'],widths=0.3,patch_artist=True,boxprops={'color':'black','facecolor':'lightgrey'},flierprops={'marker':'+','markerfacecolor':'black','color':'lightgrey'},medianprops={"linestyle":'-','color':'black'}) plt.title(d[i],fontsize=30)#通过d字典索引title plt.xticks(fontsize=20)#定义X轴标签字体大小 plt.yticks(fontsize=15) if i==1:ax.set_ylabel('AF',fontsize=30)#为所有的子图定义同一个Y轴标签,我猜测会有更聪明的办法,目前就这。 i+=1 #本次循环不会再用到i的,所以增加1。 #以下为添加非参数检验的结果 y_max=df.max().max()#计算df中最大值,第一次max得出两列各自的最大值,也就是2个值。第二次max从刚2个值中再择出最大值。则可以得到全df的最大值。本步骤的目的是确保添加的文本在最大值的上方,不要和图片重叠了。 y_min=df.min().min()#计算df中的最小值,本步骤的目的在下面可以看到。 #df最大值-df最小值,得到图片的纵向范围,然后尝试一个合适的比例,去放置文本。这里选择的比例是10,即添加的文本的位置是在y_max上方,再加整图纵向范围的十分之一长度的位置。这是多次尝试的结果。当然也可以使用绝对距离,直接y_max加某数即可。不能直接使用y_max,不然会和箱线图重叠。 #这里plt.plot()里面的值,含义是position,即画出一条[x1=1,x2=2][y1=[y_max+(y_max-y_min)/10,y2=y_max+(y_max-y_min)/10]的线。发现了吗,y1=y2,所以它其实就是一条平行于x轴的横线。 plt.plot([1,2], [y_max+(y_max-y_min)/10,y_max+(y_max-y_min)/10], linewidth=1, color='k') #再画两条纵线 plt.plot([1,1], [y_max+(y_max-y_min)/10,y_max+(y_max-y_min)/10-(y_max-y_min)/20], linewidth=1, color='k') plt.plot([2,2], [y_max+(y_max-y_min)/10,y_max+(y_max-y_min)/10-(y_max-y_min)/20], linewidth=1, color='k') #在横向上方中间的位置加上p值。中间的位置需要自己找,毕竟fontsize、p值小数点后位数,都会影响其位置。 plt.text(1.30,y_max+(y_max-y_min)/9,f'P={round(pvalue,4)}',fontsize=15,color='blue') #为全图加上title fig.suptitle('My boxline plot',fontsize=35) #保存图片,dpi可以增加清晰度。 plt.savefig('my_boxline.jpg',dpi=500)
图里的结果可见,fig1_data、fig2_data的新旧数据均差异显著,而fig3_data两组数据之间没有相关性(P>0.05)。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)