之前我们介绍过这样的plot(复现《nature communications》图表(二):一劳永逸,R语言一键画表达量箱线图并添加显著性),关于基因表达箱线图并添加显著性标记的作图,小伙伴希望能有python版本,所以这里在python中展示一下,其实在之前的(【1:1复刻R版】python版火山图函数一键出图,【1:1复刻Cell】python版单细胞多组差异基因火山图可视化函数)就说过,要想达到R的ggplot2效果,python中matplotlib结合seaborn就是它的平替。这里我们将复现过程包装在一个函数中了,如果您自己需要单独理解,拆解函数即可,很多参数都是默认,比如字体什么的,自行调整即可。
加载库:
#导入库import seaborn as snsimport matplotlib.pyplot as pltimport pandas as pdimport numpy as npimport itertoolsfrom scipy.stats import ttest_indfrom statannotations.Annotator import Annotator
df = pd.read_csv('./Exp.csv')df.head()
def ks_boxplot_exp(df, group_col, value_col, order=None, figsize=(3,3),palette="Set2", x_angle=45, log=False,tick_size=3,frame=True):"""df : pd.DataFrame,宽表格式数据,包含group,不同基因表达量group_col : str,分组列名#gene_cols : list,要绘制的基因名列表order : list,分组顺序设置palette : 分组颜色设置,可以是列表,也可以是固定每组颜色的字典figsize : 整体大图大小尺寸x_angle:x轴标签文字角度log:是否需要对数据进行对数转化处理,默认False"""if order is None:order = df[group_col].unique().tolist()plot_df = df.copy()#数据做一下log转化if log:plot_df[value_col] = np.log2(plot_df[value_col] + 1)plt.figure(figsize=figsize, dpi=300)# 箱线图ax = sns.boxplot(data=plot_df, x=group_col, y=value_col, order=order,palette=palette, fliersize=0,width=0.6)# 带抖动散点sns.stripplot(data=plot_df, x=group_col, y=value_col, order=order,jitter=True, size=2, alpha=0.7,palette=palette, dodge=False, ax=ax)# 两两组合 t 检验pairs = list(itertools.combinations(order, 2))p_values = []for g1, g2 in pairs:vals1 = plot_df.loc[plot_df[group_col]==g1, value_col].dropna()vals2 = plot_df.loc[plot_df[group_col]==g2, value_col].dropna()stat, p = ttest_ind(vals1, vals2, equal_var=False)p_values.append(p)# 显著性标记annotator = Annotator(ax, pairs, data=plot_df, x=group_col, y=value_col, order=order)annotator.configure(test=None, text_format='star', loc='inside', verbose=0,fontsize=4)annotator.set_pvalues(p_values)annotator.annotate()for line in ax.lines:line.set_color('black')line.set_linewidth(0.5)# 设置标题和坐标轴ax.set_title(value_col, fontsize=6)ax.set_ylabel("")ax.set_xlabel("")plt.xticks(rotation=x_angle)ax.tick_params(axis='both', which='major', labelsize=tick_size)if frame:ax.spines['top'].set_visible(True)ax.spines['right'].set_visible(True)else:ax.spines['top'].set_visible(False)ax.spines['right'].set_visible(False)plt.tight_layout()plt.show()
ks_boxplot_exp(df=df, group_col='Type', value_col='CXCL8', log=True, figsize=(1.5,2.5), x_angle=90, tick_size=5)
ks_boxplot_exp(df=df, group_col='Type', value_col='CXCL8', log=True, figsize=(1.5,2.5), x_angle=90, tick_size=5, frame=False)
ks_boxplot_exp(df=df, group_col='Type', value_col='CXCL8', log=True, figsize=(1.5,2.5), x_angle=90, tick_size=5, frame=False, order=['Critical', 'Severe', 'Mild','Asymptomatic'])
#循环plot多个基因gene_cols = ['CXCL8','MMP8','TLR4']for gene in gene_cols: ks_boxplot_exp(df=df, group_col='Type', value_col=gene, log=True, figsize=(1.5,2.5), x_angle=90, tick_size=5)
