Seaborn 写入了错误的子图

问题描述 投票:0回答:1

我试图在一个图中绘制多个图,并发现了一个错误,其中

axS[i] = sns.boxplot(plot)
导致 Seaborn 选择最后一个子图,就好像它忘记了
i
的值一样。注意 print 语句和指向子图的指针的位置——它们应该匹配,但是
sns.boxplot
线把它们弄乱了。

df = pd.read_csv(fold+file,index_col=1)
print(df.columns)
types = ['all cells','1 endothelial','2 immune','3 tumor','4 active fibroblast','5 stromal']
fig,axS = plt.subplots(6,1,sharex=True,figsize=(20,8))
for i,ty in enumerate(types):
    
    if i == 0:
        plot = df.loc[:,bioms]
    else:
        key = df.loc[:,'SVM_primary'] == ty
        sdf = df.loc[key,bioms]
        plot = sdf
    print('\n',i,ty)
    print(axS[i])               #First important print statement
    axS[i] = sns.boxplot(plot)
    print(axS[i])               #Second: should be identical, but it's not!
    axS[i].title.set_text(ty)                  
plt.xticks(rotation = 90)
fig.tight_layout()
plt.show()

输出为:

0 all cells

AxesSubplot(0.125,0.77;0.775x0.11)

AxesSubplot(0.125,0.11;0.775x0.11)


 1 1 endothelial

AxesSubplot(0.125,0.638;0.775x0.11)    # 

AxesSubplot(0.125,0.11;0.775x0.11)     # this pointer should be the same as the one above it


 2 2 immune

AxesSubplot(0.125,0.506;0.775x0.11)

AxesSubplot(0.125,0.11;0.775x0.11)


 3 3 tumor

AxesSubplot(0.125,0.374;0.775x0.11)

AxesSubplot(0.125,0.11;0.775x0.11)


 4 4 active fibroblast

AxesSubplot(0.125,0.242;0.775x0.11)

AxesSubplot(0.125,0.11;0.775x0.11)


 5 5 stromal

AxesSubplot(0.125,0.11;0.775x0.11)

AxesSubplot(0.125,0.11;0.775x0.11)   

脚本正确识别了

i
,但在两个
print(axS[i])
语句中,第一个正确识别了指向新子图的唯一指针,然后在调用SNS图后,它认为这是最后一个子图(就好像
i
变成了5)每次调用
sns.boxplot
时)。我希望我错过了一些东西。

python matplotlib seaborn
1个回答
0
投票

这不是seaborn的错误,这是对seaborn工作原理的误解(以及对python的一般误解)。

从普遍的误解开始。假设你有一个清单。

x = [1, 2, 3]

如果您为其建立索引并更改值,则会更新列表。

x[1] = 5
print(x) # [1, 5, 3]

因此,当您调用

sns.boxplot
时,它会返回一个轴对象,您可以用它来覆盖
axS[i]

当您调用

sns.boxplot
时,您并没有告诉seaborn要使用哪个轴,因此默认情况下它将使用最新图形的最后一个轴。

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

x = np.arange(0, 10, 0.01)
y1 = x**2
y2 = np.sin(x)

fig, axes = plt.subplots(1, 2)
a = sns.lineplot(x=x, y=y1)

看到它如何使用图中的最后一个轴了吗?我将返回保存到

a
,我可以检查它是否等于最后一个轴。

print(a == axes[-1])  # True

要在正确的轴上绘图,您必须将其作为关键字参数传递给seaborn。

fig, axes = plt.subplots(1, 2)
a = sns.lineplot(x=x, y=y1, ax=axes[0])
b = sns.lineplot(x=x, y=y2, ax=axes[1])

作为支票:

print(a == axes[0])  # True
print(b == axes[1])  # True

因此,总之,将轴传递给箱线图调用,并且不要用返回值覆盖轴列表(尽管一旦绘制到正确的轴,它就不会执行任何操作)。

sns.boxplot(plot, ax=axS[i])
© www.soinside.com 2019 - 2024. All rights reserved.