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

Seaborn绘制子图异常:指定子图被覆盖为最后一个子图

问题:Seaborn绘制多子图时,子图指针被意外覆盖为最后一个子图

尝试在单个画布中绘制多个子图时发现异常:执行axS[i] = sns.boxplot(plot)后,Seaborn始终选择最后一个子图,两次打印axS[i]的结果不一致——第一次能正确指向对应子图,调用绘图函数后指针变为最后一个子图的指针。

问题代码

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)   

原因分析与解决方法

问题根源

  • Seaborn的boxplot函数如果不指定ax参数,会默认使用当前活动的Matplotlib轴对象(创建6个子图后,默认活动轴是最后一个子图axS[5])
  • 执行axS[i] = sns.boxplot(plot)时,会把boxplot返回的默认轴(也就是最后一个子图)覆盖掉原来的axS[i],导致后续设置标题等操作全部指向最后一个子图

解决方法

不要重新赋值axS[i],而是给boxplot指定ax参数,直接在目标子图上绘制:
将axS[i] = sns.boxplot(plot)修改为:

sns.boxplot(data=plot, ax=axS[i])

修改后的完整代码

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])               
    sns.boxplot(data=plot, ax=axS[i])  # 指定ax参数,不覆盖原轴对象
    print(axS[i])               
    axS[i].title.set_text(ty)                  
plt.xticks(rotation = 90)
fig.tight_layout()
plt.show()

这样修改后,axS[i]始终指向你创建的对应子图,绘图和标题设置都会正确作用在目标子图上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 17:20:20