首页 > 解决方案 > Python 堆叠条形图,其中 y 轴刻度是线性的,但条形填充是 10 秒数量级的对数

问题描述

正如标题所解释的,我试图重现一个堆叠条形图,其中 y 轴刻度是线性的,但绘图的内部填充(即堆叠条)是对数的,并且按 10 秒的顺序分组。

我之前在 R-Studio 上使用内部包制作了这个图,但是我试图用其他程序(python)重现这个图来验证和确认我的分析。

数据的快速描述/更多细节:

我有成千上万的克隆细胞信息条目。它们有多个标识符,例如“Strain”、“Sample”、“cloneID”,以及每个克隆的频率值(“cloneFraction”)。

这是我正在使用的数据集的 .head(),让您了解我的数据

我正在尝试重现我用 R-Studio 制作的以下情节: this one here

该图将数据集根据频率分组,前 10 个最频繁的分组为红色,其次是下一个前 100 个、下一个 1000 等。y 轴的刻度为 0.00-1.00,但也有 100 % 比例不会改变,在这种情况下它们的意思是一样的。

这只是为了获得一个想法并可视化我是否有大克隆(前 10 个)以及它们在频率上占据了整个数据集的多少 - 即红色堆栈越大,我拥有的克隆越大,表示有一个重要的克隆在我的几个选定单元格的样本中展开。

到目前为止我做了什么:

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()

我在这里得到了这个情节

现在,我意识到堆叠图中没有顺序,所以最常见的不在顶部 - 它只是按照我的数据集中条目的顺序堆叠(我假设我可以通过按列对数据框进行排序来修复出于兴趣)。

除了当我使用对数刻度(这是次要问题)时轴混乱并且没有给出我的百分比之外,我似乎无法/不知道如何按频率对数据条目进行分组,如上所述。

我尝试过诸如:

temp = X.SOME_IDENTIFIER.value_counts()
temp2 = temp.head(10)
if len(temp) > 10:
    temp2['remaining {0} items'.format(len(temp) - 10)] = sum(temp[10:])
temp2.plot(kind='pie')

只是想看看我是否可以以正确的方式将它们分开,但这并没有达到我想要的效果(除了作为饼图,但我在我的代码中改变了它)。

我也尝试过使用 iloc[n:n] 来选择特定的条目,但我似乎也无法让它工作,因为当我尝试将它添加到我上面用来绘制图表的代码中时出现错误 -如果我在代码中没有其他花哨的东西(%比例等)使用它,它会在堆叠的条形图中混淆,并且只绘制我数据中所有 4 个样本中的前 10 个,而不是每个样本的前 10 个。我也不知道如何获得下一个 100、1000 等。

如果您有任何建议并能以任何方式提供帮助,我们将不胜感激!

谢谢

标签: pythonpandasmatplotlibjupyter-notebook

解决方案


我修复了我想用以下内容做的事情:

我创建了一个新列,其中包含我的样本所属的类别,基于它们的值(即,如果它们是最常见的前 10 个,接下来是 100 个,等等)。

df['category']='10001+'

for sampleref in df.sample_ref.unique().tolist():

print(f'Setting sample {sampleref}')

df.loc[df[df.sample_ref == sampleref].nlargest(10000, 'cloneCount')['category'].index,'category']='1001-10000'

df.loc[df[df.sample_ref == sampleref].nlargest(1000, 'cloneCount')['category'].index,'category']='101-1000'

df.loc[df[df.sample_ref == sampleref].nlargest(100, 'cloneCount')['category'].index,'category']='11-100'

df.loc[df[df.sample_ref == sampleref].nlargest(10, 'cloneCount')['category'].index,'category']='top10'

此代码从最大的组(10001+)开始,然后越来越小,以包括可能落入下一个大组的重叠样本。

在此之后,我使用以下代码绘制了样本:

fig, ax = plt.subplots(figsize=(15,7))


df.groupby(['Sample','category']).sum()['cloneFraction'].unstack().plot(ax=ax, kind="bar", stacked=True)


plt.xticks(rotation=0)

plt.gca().yaxis.set_major_formatter(mtick.PercentFormatter(1))

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[::-1], labels[::-1], title='Clonotype',bbox_to_anchor=(1.04,0), loc="lower left", borderaxespad=0)

结果如下:
这里

我希望这可以帮助任何在同样问题上苦苦挣扎的人!


推荐阅读