You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中绘制Y轴为线性刻度、条形填充按10的量级分组的对数堆叠柱状图

如何用Python复现按克隆频率量级分组的堆叠柱状图?

我来帮你搞定这个堆叠柱状图的复现问题——从你描述的需求来看,核心是要按样本独立划分克隆频率的量级组,再绘制堆叠占比图,这和你之前尝试的直接分组统计确实有区别。咱们先理清楚问题,再一步步给出解决方案。

需求回顾

你需要实现的堆叠柱状图满足以下要求:

  • Y轴采用线性刻度(0-100%),展示克隆频率的占比总和
  • 每个样本的堆叠条内部按克隆频率的10量级分组:前10个最高频率克隆为一组,接下来100个为一组,再接下来1000个为一组,以此类推
  • 不同组用不同颜色区分(比如前10组用红色),用来直观判断样本是否存在大规模克隆扩增

数据说明

你拥有包含数千条克隆细胞信息的数据集,核心字段包括:

  • Strain、Sample、cloneID:标识符字段
  • cloneFraction:每个克隆的频率值(最终要转化为占比)

已尝试的代码及问题

你之前写的代码如下:

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
%matplotlib inline
MYDATAFRAME.groupby(['Sample','cloneFraction']).size().groupby(level=0).apply(lambda x: 100 * x / x.sum()).unstack().plot(kind='bar',stacked=True, legend=None)
plt.yscale('log')
plt.gca().yaxis.set_major_formatter(mtick.PercentFormatter())
plt.show()

但遇到了三个关键问题:

  • 堆叠顺序不符合要求:条形按数据集条目顺序堆叠,未按频率从高到低排列
  • 对数刻度下Y轴无法正确显示百分比格式(次要问题,其实你需求是线性刻度,这个可以直接调整)
  • 核心问题:无法按样本独立划分10/100/1000的量级分组,只能全局筛选,而非每个样本各自分组

解决方案思路及代码示例

咱们分两步走:先处理数据,按样本分组并划分频率量级;再绘制堆叠柱状图。

步骤1:数据预处理(核心)

我们需要对每个样本单独处理:

  1. 按Sample分组,对每个样本的cloneFraction降序排序
  2. 为每个克隆分配所属的量级组(比如"Top 10"、"11-110"、"111-1110"等)
  3. 计算每个样本内,各量级组的总频率占比

代码如下:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick

# 假设你的数据集叫df,先确保cloneFraction是数值类型
df = MYDATAFRAME.copy()
df['cloneFraction'] = pd.to_numeric(df['cloneFraction'])

# 定义分组函数:对单个样本的克隆按频率降序后,划分量级组
def assign_group(clone_series):
    # 按频率降序排序
    sorted_clones = clone_series.sort_values(ascending=False).reset_index(drop=True)
    # 为每个克隆分配组标签
    groups = []
    for idx in sorted_clones.index:
        if idx < 10:
            groups.append('Top 10')
        elif idx < 10+100:
            groups.append('11-110')
        elif idx < 10+100+1000:
            groups.append('111-1110')
        else:
            groups.append('>1110')  # 剩下的克隆归为一组
    sorted_clones = sorted_clones.to_frame('cloneFraction')
    sorted_clones['group'] = groups
    # 计算每组的总占比(转化为百分比)
    group_sum = sorted_clones.groupby('group')['cloneFraction'].sum() * 100
    return group_sum

# 按Sample分组应用函数,得到每个样本的各组占比
grouped_data = df.groupby('Sample').apply(assign_group).unstack(fill_value=0)
# 调整列的顺序,确保堆叠顺序是从高量级到低量级(Top10在最上面)
grouped_data = grouped_data[['Top 10', '11-110', '111-1110', '>1110']]

步骤2:绘制堆叠柱状图

现在用处理好的数据绘图,设置颜色、Y轴格式等:

# 设置颜色,比如Top10用红色,其他组用深浅不同的灰色
colors = ['#e74c3c', '#95a5a6', '#bdc3c7', '#ecf0f1']

# 绘制堆叠柱状图
ax = grouped_data.plot(kind='bar', stacked=True, color=colors, figsize=(12, 6), legend=True)

# 设置Y轴为线性刻度,显示百分比
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
ax.set_ylim(0, 100)  # 固定Y轴范围0-100%

# 添加标题和标签
plt.title('Clone Expansion by Frequency Groups per Sample', fontsize=14)
plt.xlabel('Sample', fontsize=12)
plt.ylabel('Total Clone Fraction (%)', fontsize=12)
plt.legend(title='Clone Frequency Groups', bbox_to_anchor=(1.05, 1), loc='upper left')

# 调整布局,防止图例被截断
plt.tight_layout()
plt.show()

关键问题的解决说明

  1. 堆叠顺序问题:通过grouped_data的列顺序指定,确保"Top 10"组在最上方(堆叠顺序是列的顺序,先出现的列在最下面,后出现的在上面,如果你想Top10在最下面,调整列顺序即可)
  2. Y轴百分比格式:用线性刻度直接配合mtick.PercentFormatter(),完美解决之前对数刻度的问题
  3. 按样本独立分组:通过groupby('Sample').apply(assign_group)实现每个样本单独排序、分组,完全满足你“每个样本各自的前10个及后续量级分组”的需求

内容的提问来源于stack exchange,提问作者Kroky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:23:14