如何绘制按患者分组、区分普通/稀有细胞类型的堆叠柱状图
如何绘制按患者分组、区分普通/稀有细胞类型的堆叠柱状图
看起来你想要的是每个患者对应两个堆叠柱状图——一个展示该患者中普通细胞类型的比例分布,另一个展示稀有细胞类型的比例分布对吧?我来帮你调整代码实现这个需求~
核心思路很简单:我们需要把「患者名称」和「细胞类型类别(普通/稀有)」组合成一个新的分组列,这样每个患者就会对应两个独立的x轴类别,分别承载普通/稀有细胞的堆叠比例。下面是修改后的完整代码:
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from random import choice # 生成模拟数据 celltype_name = [choice(['Myeloid','B','T','NK','CAF','pDC']) for i in range(100)] celltype2_name= [choice(['rare','common']) for i in range(100)] patient_name = [choice(['P01','P02','P03','P04']) for i in range(100)] df = pd.DataFrame([celltype_name, celltype2_name, patient_name]).T df.columns = ['celltype', 'celltype2', 'patient_name'] df['patient_name'] = pd.Categorical(df['patient_name'], ['P01','P02','P03','P04']) # 关键步骤:创建患者+细胞类型类别的组合列,确保每个患者的common/rare柱子挨在一起 df['patient_celltype2'] = df['patient_name'] + '_' + df['celltype2'] df['patient_celltype2'] = pd.Categorical( df['patient_celltype2'], [f"{p}_{ct2}" for p in ['P01','P02','P03','P04'] for ct2 in ['common','rare']] ) # 绘制堆叠比例柱状图 ax = sns.histplot( data=df, x="patient_celltype2", hue="celltype", multiple="fill", stat="proportion", discrete=True, shrink=.8, legend=True, linewidth=0.2, ) # 优化x轴标签,让显示更清晰 ax.set_xticklabels(['P01(普通)', 'P01(稀有)', 'P02(普通)', 'P02(稀有)', 'P03(普通)', 'P03(稀有)', 'P04(普通)', 'P04(稀有)']) plt.xticks(rotation=45) # 移动图例到右上角 sns.move_legend(ax, "upper left", bbox_to_anchor=(1, 1)) plt.tight_layout() # 自动调整布局,避免标签被截断 plt.show()
代码说明:
- 组合分组列:通过
patient_name + "_" + celltype2生成新的x轴类别,同时用pd.Categorical指定顺序,保证每个患者的「普通」和「稀有」柱子是相邻的,不会乱序。 - 调整x轴标签:把默认的长标签改成更易懂的格式,同时旋转45度避免重叠。
- 保留原风格:沿用你原来的
histplot参数,确保堆叠比例的逻辑和之前一致,只是扩展了x轴的分组维度。
运行这段代码后,你就能看到每个患者对应两个堆叠柱子,分别展示普通/稀有细胞类型的比例分布啦~
备注:内容来源于stack exchange,提问作者Knotnet




