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

如何将循环生成的matplotlib箱线图排布到指定子图网格

问题背景

我知晓该问题此前已被多次提问,但我耗费了大量时间仍未找到解决方案,尽管我确信其实现逻辑十分简单。我的数据来源于3个结构完全一致的独立DataFrame,为绘制箱线图,我已经完成了数据转置等预处理操作。

原有实现代码如下:

columnname = list(cm)
max = len(columnname)-1
for i in range(0,max):
    cm2 = cm[columnname[i]]
    vz2 = vz[columnname[i]]
    models2 = models[columnname[i]]
    columns = [cm2, vz2, models2]
    name = str(cm2.name)
    fig, ax = plt.subplots()
    ax.boxplot(columns)
    ax.set_ylabel('$')
    ax.set_title(name)

遇到的问题:尝试直接在subplots中传入(2,4)参数将循环生成的图表排布到指定网格时,代码无法运行,抛出如下报错:

AttributeError: 'numpy.ndarray' object has no attribute 'boxplot'

报错原因

当给plt.subplots()传入多行多列的网格参数时,返回的坐标轴对象是对应网格结构的numpy数组,不是单个可直接调用绘图方法的坐标轴实例,直接对数组调用boxplot就会触发属性不存在的报错。另外原代码在每次循环内都新建独立画布,本身也无法实现多图排布到同一网格的效果。

解决方案

按以下步骤修改即可实现指定网格排布:

  • 循环外提前初始化指定网格尺寸的画布和坐标轴组,按需设置画布大小避免内容拥挤
  • 将二维结构的坐标轴数组展平为一维,方便循环时按顺序索引到单个子图的坐标轴
  • 移除循环内新建画布的代码,每次循环取对应位置的单个坐标轴对象完成绘图
  • 所有图绘制完成后自动调整子图间距,避免标题、标签互相遮挡

修改后的参考代码:

import matplotlib.pyplot as plt

columnname = list(cm)
# 初始化2行4列的子图网格,figsize可根据展示需求调整尺寸
fig, axes = plt.subplots(nrows=2, ncols=4, figsize=(16, 8))
# 将2*4的二维坐标轴数组展平为长度8的一维数组,方便按索引取值
axes = axes.flatten()

for i in range(len(columnname)-1):
    cm2 = cm[columnname[i]]
    vz2 = vz[columnname[i]]
    models2 = models[columnname[i]]
    columns = [cm2, vz2, models2]
    name = str(cm2.name)
    # 取出当前循环对应的单个坐标轴对象
    ax = axes[i]
    ax.boxplot(columns)
    ax.set_ylabel('$')
    ax.set_title(name)

# 如果实际绘图数量少于网格总数(比如仅5张图),隐藏多余的空白子图
for j in range(len(columnname)-1, len(axes)):
    axes[j].axis('off')

# 自动调整子图间距,避免文字遮挡
plt.tight_layout()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:09:25