我想在我创建的火山图中标记一些异常值。我的想法是首先为我感兴趣的列创建一个仅包含最大 3 个值(也称为我的离群值)的 df,然后使用该 df 来标记我的火山图。我已经能够将标签添加到我的绘图上,但是,因为我的绘图使用 y 轴的 -log10,所以我无法将标签置于适当的高度。如果我使用 y 轴列中的原始值,标签就会全部聚集在图表底部。当我尝试使用 y 轴的 -log10 值时,出现错误。
我所在领域的大多数人在绘制绘图后使用 adobe 来标记异常值,但我真的很想找到一种使用 python 来标记我的点的方法。
下面的示例表、代码和错误。
#example df
data = {'log2FoldChange': [15, 16, 2, 3],
'pvalue': [0.0000005, 0.00006, 0.7, 0.9],
'padj': [0.0008, 0.005, 0.0008, 0.0007],
'gene_name': ['gene1', 'gene2', 'gene3', 'gene4']}
df = pd.DataFrame(data)
display(df)
#creating a subset of my df that only highlights the 3 genes with the highest log2foldchange
outliersx = df.nlargest(3, 'log2FoldChange')
#plotting volcano plot. NOTE: y axis is the -log10 of pvalue.
plt.scatter(x=df2['log2FoldChange'],y=df2['pvalue'].apply(lambda x:-np.log10(x)),s=1)
#dash marks
plt.axvline(0.6,color="grey",linestyle="--")
plt.axvline(-0.6,color="grey",linestyle="--")
plt.axhline(1.3,color="grey",linestyle="--")
#highlighting significantly down regulated genes
down = df2[(df2['log2FoldChange']<=-0.6)&(df2['pvalue']<=0.05)]
plt.scatter(x=down['log2FoldChange'],y=down['pvalue'].apply(lambda x:-np.log10(x)),s=3,label="Down-regulated",color="blue")
#highlighting significantly upregulated genes
up = df2[(df2['log2FoldChange']>=0.6)&(df2['pvalue']<=0.05)]
plt.scatter(x=up['log2FoldChange'],y=up['pvalue'].apply(lambda x:-np.log10(x)),s=3,label="Up-regulated",color="red")
plt.xlabel("logFC")
plt.ylabel("-logFDR")
#axis labels
plt.xlabel("log2foldchange")
plt.ylabel("-log10(pvalue)")
#Here I am using ax.annotate to try and annotate the three largest log2foldchange data points in my data.
outliersx[['log2FoldChange','pvalue','gene_name']].apply(lambda row: ax.text(*row),axis=1);
我意识到我的所有标签都聚集在底部,因为我使用原始 p 值而不是 -log10 p 值作为标签的坐标。因此,我接下来尝试通过应用以下代码来使用 pvalues 的 -log10,但出现错误。
outliersx[['log2FoldChange',outliersx['pvalue'].apply(lambda x:-np.log10(x)),'gene_name']].apply(lambda row: ax.text(*row),axis=1);
#TypeError: unhashable type: 'Series'
我对为什么会收到该错误感到有点困惑,并且我希望获得有关如何使用 pvalue 列的 -log10 作为应用标签的 y 坐标的指导。
我会像你一样开始,然后添加注释:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
data = {'log2FoldChange': [15, 16, 2, 3],
'pvalue': [0.0000005, 0.00006, 0.7, 0.9],
'padj': [0.0008, 0.005, 0.0008, 0.0007],
'gene_name': ['gene1', 'gene2', 'gene3', 'gene4']}
df = pd.DataFrame(data)
plt.figure(figsize=(8, 6))
plt.scatter(df['log2FoldChange'], -np.log10(df['pvalue']), s=10, color='grey')
down = df[(df['log2FoldChange'] <= -0.6) & (df['pvalue'] <= 0.05)]
up = df[(df['log2FoldChange'] >= 0.6) & (df['pvalue'] <= 0.05)]
plt.scatter(down['log2FoldChange'], -np.log10(down['pvalue']), s=30, color='blue', label="Down-regulated")
plt.scatter(up['log2FoldChange'], -np.log10(up['pvalue']), s=30, color='red', label="Up-regulated")
plt.axvline(x=0.6, color="grey", linestyle="--")
plt.axvline(x=-0.6, color="grey", linestyle="--")
plt.axhline(y=-np.log10(0.05), color="grey", linestyle="--")
plt.xlabel("log2FoldChange")
plt.ylabel("-log10(pvalue)")
plt.title("Volcano Plot")
plt.legend()
outliers = df.nlargest(3, 'log2FoldChange')
for index, row in outliers.iterrows():
plt.text(row['log2FoldChange'], -np.log10(row['pvalue']), row['gene_name'], fontsize=9, ha='right')
给予