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

matplotlib多行多列子图报错numpy.ndarray无xaxis属性咨询

问题描述
  • 尝试创建包含多个子图的可视化图表时,触发以下报错:
AttributeError: 'numpy.ndarray' object has no attribute 'xaxis'
  • 触发报错的代码如下:
plt.figure()
n_cols = 6
n_rows = int(len(df.foo.unique()) / n_cols) # 计算结果为4
fn, axis = plt.subplots(nrows=n_rows, ncols=n_cols, figsize=(30, 25))
for i in range(len(df.foo.unique())):
    sb.scatterplot(x='var1', y='var2', hue='foo', data=df[df.foo == i], ax=axis[i])

代码说明:字段foo取值范围为0-23,共24个唯一值。

  • 当把子图参数修改为1行12列时,代码可正常运行无报错,对应代码如下:
plt.figure()
fn, axis = plt.subplots(nrows=1, ncols=12, figsize=(30, 25))
for i in range(len(df.foo.unique())):
    sb.scatterplot(x='var1', y='var2', hue='foo', data=df[df.foo == i], ax=axis[i])
  • 报错完整堆栈信息:
File c:\Users\user\anaconda3\envs\ml\lib\site-packages\seaborn\_decorators.py:46, in _deprecate_positional_args.<locals>.inner_f(*args, **kwargs)
     36     warnings.warn(
     37         "Pass the following variable{} as {}keyword arg{}: {}. "
     38         "From version 0.12, the only valid positional argument "
   (...)
     43         FutureWarning
     44     )
     45 kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
---> 46 return f(**kwargs)

File c:\Users\user\anaconda3\envs\ml\lib\site-packages\seaborn\relational.py:825, in scatterplot(x, y, hue, style, size, data, palette, hue_order, hue_norm, sizes, size_order, size_norm, markers, style_order, x_bins, y_bins, units, estimator, ci, n_boot, alpha, x_jitter, y_jitter, legend, ax, **kwargs)
    822 if not p.has_xy_data:
    823     return ax
---> 825 p._attach(ax)
    827 p.plot(ax, kwargs)
    829 return ax

File c:\Users\user\anaconda3\envs\ml\lib\site-packages\seaborn\_core.py:1134, in VectorPlotter._attach(self, obj, allowed_types, log_scale)
...
-> 1134     axis = getattr(ax, f"{var}axis")
   1135     seed_data = self.plot_data[var]
   1136     if var_type == "categorical":

AttributeError: 'numpy.ndarray' object has no attribute 'xaxis'
报错原因

核心原因是plt.subplots()返回的坐标轴数组维度,会随子图的行列设置变化:

  • 当设置nrows=1且ncols>1(或者ncols=1且nrows>1)时,返回的axis是一维numpy数组,直接用axis[i]索引就能拿到单个子图的坐标轴对象,所以1行12列的代码可以正常运行。
  • 当同时设置nrows>1且ncols>1时,返回的axis是二维numpy数组,形状为(n_rows, n_cols)。这时候用axis[i]索引,拿到的不是单个坐标轴对象,而是第i行对应的整行子图数组(类型仍然是numpy.ndarray),把数组传给scatterplot的ax参数,seaborn尝试访问数组的xaxis属性自然会触发报错。
修复方法

两种常用改法任选其一即可:

  1. 把二维坐标轴数组展平为一维,再按索引取值:
plt.figure()
n_cols = 6
n_rows = int(len(df.foo.unique()) / n_cols) # 4
fn, axis = plt.subplots(nrows=n_rows, ncols=n_cols, figsize=(30, 25))
# 展平二维数组为一维
axis = axis.flatten()
for i in range(len(df.foo.unique())):
    sb.scatterplot(x='var1', y='var2', hue='foo', data=df[df.foo == i], ax=axis[i])
  1. 索引时传入行列坐标定位单个子图:
plt.figure()
n_cols = 6
n_rows = int(len(df.foo.unique()) / n_cols) # 4
fn, axis = plt.subplots(nrows=n_rows, ncols=n_cols, figsize=(30, 25))
for i in range(len(df.foo.unique())):
    # 计算当前索引对应的行号、列号
    row_idx = i // n_cols
    col_idx = i % n_cols
    sb.scatterplot(x='var1', y='var2', hue='foo', data=df[df.foo == i], ax=axis[row_idx, col_idx])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:39:15