0

0

Matplotlib subplots 轴对象解包错误解析与修正

聖光之護

聖光之護

发布时间:2025-10-07 14:18:01

|

533人浏览过

|

来源于php中文网

原创

Matplotlib subplots 轴对象解包错误解析与修正

本文旨在解决在使用 matplotlib.pyplot.subplots 创建多子图时,因轴对象解包不当导致的 AttributeError: 'numpy.ndarray' object has no attribute 'bar' 错误。通过详细分析 subplots 的返回值机制,本文将展示如何正确地解包和访问单个轴对象,从而有效避免此类常见的绘图问题,确保Seaborn等库的绘图函数能够正确调用轴方法。

在使用 matplotlib.pyplot 和 seaborn 进行数据可视化时,attributeerror: 'numpy.ndarray' object has no attribute 'bar' 是一个常见的错误,尤其是在创建包含多个子图的图形布局时。这个错误通常发生在尝试在一个 numpy.ndarray 类型的对象上调用绘图方法(如 bar、countplot 等)时,而这些方法实际上应该在 matplotlib.axes.axes 对象上调用。问题的根源在于对 plt.subplots 返回值的误解和不正确的解包操作。

理解 plt.subplots 的返回值

plt.subplots 函数用于创建一个包含多个子图的图形。它的返回值是一个元组,通常包含两个元素:

  1. fig: 一个 matplotlib.figure.Figure 对象,代表整个图形窗口。
  2. ax: 一个或一组 matplotlib.axes.Axes 对象,代表图中的一个或多个子图(坐标系)。

关键在于 ax 的类型取决于你如何调用 plt.subplots:

  • 单个子图: 当 nrows=1 和 ncols=1 (或省略这些参数,因为它们默认都是1) 时,ax 将直接是一个 matplotlib.axes.Axes 对象。
    fig, ax = plt.subplots() # ax 是一个 Axes 对象
  • 多个子图 (一维排列): 当 nrows > 1 且 ncols = 1,或 nrows = 1 且 ncols > 1 时,ax 将是一个 numpy.ndarray 对象,其中包含多个 Axes 对象。
    fig, axes = plt.subplots(nrows=2, ncols=1) # axes 是一个包含两个 Axes 对象的 NumPy 数组
    fig, axes = plt.subplots(nrows=1, ncols=2) # axes 是一个包含两个 Axes 对象的 NumPy 数组
  • 多个子图 (二维网格): 当 nrows > 1 且 ncols > 1 时,ax 将是一个二维的 numpy.ndarray 对象,其形状与 (nrows, ncols) 对应。
    fig, axes = plt.subplots(nrows=2, ncols=2) # axes 是一个 2x2 的 NumPy 数组

错误示例分析

考虑以下导致 AttributeError 的代码片段:

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

# 假设 dataset 是一个 DataFrame,包含 'class_label' 列
# 这里创建一个示例数据集
data = {'class_label': np.random.choice(['A', 'B', 'C', 'D'], 100)}
dataset = pd.DataFrame(data)

# 错误的代码示例
fig, (ax1) = plt.subplots(ncols=2, figsize=(25, 7.5), dpi=100)
fig.suptitle(f'Counts of Observation Labels in ciciot_2023 ', fontsize=25)
sns.countplot(x="class_label", palette="OrRd_r", data=dataset, order=dataset['class_label'].value_counts().index, ax=ax1)

ax1.set_title('ciciot2023', fontsize=20)
ax1.set_xlabel('label', fontsize=15)
ax1.set_ylabel('count', fontsize=15)
ax1.tick_params(labelrotation=90)

plt.show()

在这个例子中,plt.subplots(ncols=2, ...) 明确要求创建两个列的子图。根据上面的解释,plt.subplots 会返回一个 fig 对象和一个包含两个 Axes 对象的 numpy.ndarray。然而,代码中使用了 fig, (ax1) = ... 这样的解包方式。这里的 (ax1) 仅仅是给变量 ax1 加上了括号,它并没有实现数组的解包。因此,ax1 变量实际上接收到的是整个 numpy.ndarray 对象,而不是第一个 Axes 对象。

当 sns.countplot 函数尝试在 ax=ax1 上绘图时,它会内部调用 ax1.bar 方法。但由于 ax1 是一个 numpy.ndarray 对象,它并没有 bar 这个方法,从而引发 AttributeError: 'numpy.ndarray' object has no attribute 'bar'。

阶跃星辰开放平台
阶跃星辰开放平台

阶跃星辰旗下开放平台,提供文本大模型、多模态大模型、繁星计划

下载

正确的解包与修正方法

要解决这个问题,关键在于正确地解包 plt.subplots 返回的 Axes 数组。当 ncols=2 时,你需要提供两个变量来接收这两个 Axes 对象。

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

# 假设 dataset 是一个 DataFrame,包含 'class_label' 列
data = {'class_label': np.random.choice(['A', 'B', 'C', 'D'], 100)}
dataset = pd.DataFrame(data)

# 正确的代码示例
# 当 ncols=2 时,需要解包为两个 Axes 对象,例如 (ax1, ax2)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(25, 7.5), dpi=100)

fig.suptitle(f'Counts of Observation Labels in ciciot_2023 ', fontsize=25)

# 现在 ax1 是一个 Axes 对象,可以正确地传递给 seaborn
sns.countplot(x="class_label", palette="OrRd_r", data=dataset, order=dataset['class_label'].value_counts().index, ax=ax1)

ax1.set_title('ciciot2023', fontsize=20)
ax1.set_xlabel('label', fontsize=15)
ax1.set_ylabel('count', fontsize=15)
ax1.tick_params(labelrotation=90)

# 如果有第二个子图,可以在 ax2 上进行绘图
# sns.countplot(x="another_label", data=dataset, ax=ax2)
# ax2.set_title('Another Plot')

plt.tight_layout(rect=[0, 0.03, 1, 0.95]) # 调整布局以避免标题重叠
plt.show()

通过将 fig, (ax1) 修改为 fig, (ax1, ax2),我们正确地将 plt.subplots 返回的 Axes 数组解包为两个独立的 Axes 对象 ax1 和 ax2。这样,ax1 就不再是 numpy.ndarray,而是真正的 matplotlib.axes.Axes 对象,其上所有绘图方法(如 bar)都可正常调用。

注意事项与最佳实践

  1. 匹配解包数量: 始终确保你用于解包 Axes 对象的变量数量与 plt.subplots 创建的子图数量相匹配。
    • plt.subplots(nrows=1, ncols=1) -> fig, ax = plt.subplots()
    • plt.subplots(nrows=1, ncols=N) 或 plt.subplots(nrows=N, ncols=1) -> fig, axes = plt.subplots(...),然后通过 axes[0], axes[1] 等访问,或者 fig, (ax1, ax2, ..., axN) = plt.subplots(...) 进行解包。
    • plt.subplots(nrows=N, ncols=M) -> fig, axes = plt.subplots(...),然后通过 axes[i, j] 访问。
  2. 灵活使用索引: 当子图数量较多或布局复杂时,使用 axes 数组的索引(如 axes[0] 或 axes[1, 0])来访问特定的 Axes 对象通常比解包到大量单独的变量更方便。
  3. squeeze=False: 如果你总是希望 ax 返回一个二维数组,即使是单行单列的布局,可以使用 plt.subplots(..., squeeze=False)。这可以使代码在不同布局下更具一致性,但需要始终使用索引访问 ax[0, 0]。
  4. 导入规范: 习惯性地导入 matplotlib.pyplot 为 plt,seaborn 为 sns,以保持代码的简洁性和可读性。

总结

AttributeError: 'numpy.ndarray' object has no attribute 'bar' 错误通常源于对 matplotlib.pyplot.subplots 返回值(特别是 Axes 对象)的误解和不当解包。通过理解 plt.subplots 如何根据 nrows 和 ncols 参数返回单个 Axes 对象或 Axes 对象的 numpy.ndarray,并采用正确的解包或索引访问方式,可以有效地避免此类错误,确保绘图代码的顺利执行。始终记住,绘图函数如 sns.countplot 需要一个 matplotlib.axes.Axes 对象作为其 ax 参数。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Go Web框架Gin接口开发与中间件设计实践
Go Web框架Gin接口开发与中间件设计实践

本专题围绕 Go 在 Web 后端开发中的主流框架 Gin 展开,系统讲解高性能接口开发与中间件机制设计。内容涵盖路由分组、请求绑定、参数校验、统一响应封装、日志与鉴权中间件实现,以及接口限流与异常处理策略。通过实战项目案例,帮助开发者构建结构清晰、性能优良的 Go Web 服务体系,提升接口开发效率与系统可维护性。

7

2026.03.19

bootstrap安装教程
bootstrap安装教程

本专题整合了bootstrap安装相关教程,阅读专题下面的文章了解更多详细操作教程。

26

2026.03.18

bootstrap框架介绍
bootstrap框架介绍

本专题整合了bootstrap框架相关介绍,阅读专题下面的文章了解更多详细内容。

167

2026.03.18

vscode 格式化
vscode 格式化

本专题整合了vscode格式化相关内容,阅读专题下面的文章了解更多详细内容。

13

2026.03.18

vscode设置中文教程
vscode设置中文教程

本专题整合了vscode设置中文相关内容,阅读专题下面的文章了解更多详细教程。

8

2026.03.18

vscode更新教程合集
vscode更新教程合集

本专题整合了vscode更新相关内容,阅读专题下面的文章了解更多详细教程。

13

2026.03.18

Gemini网页版零基础入门:5分钟上手Gemini聊天指南
Gemini网页版零基础入门:5分钟上手Gemini聊天指南

本专题专为零基础用户打造,5分钟快速掌握Gemini网页版核心用法。从账号登录到界面布局,详解如何发起对话、优化提示词及利用多模态功能。通过实战案例,教你高效获取信息、创作内容与分析数据。无论学习还是工作,轻松开启AI辅助新时代,让Gemini成为你的得力智能助手。

60

2026.03.18

Python WebSocket实时通信与异步服务开发实践
Python WebSocket实时通信与异步服务开发实践

本专题聚焦 Python 在实时通信场景中的开发实践,系统讲解 WebSocket 协议原理、长连接管理、消息推送机制以及异步服务架构设计。内容包括客户端与服务端通信实现、连接稳定性优化、消息队列集成及高并发处理策略。通过完整案例,帮助开发者构建高效稳定的实时通信系统,适用于聊天应用、实时数据推送等场景。

33

2026.03.18

Java Spring Security权限控制与认证机制实战
Java Spring Security权限控制与认证机制实战

本专题围绕 Java 后端安全体系建设展开,重点讲解 Spring Security 在权限控制与认证机制中的应用实践。内容涵盖用户认证流程、权限模型设计、JWT 鉴权方案、OAuth2 集成以及接口安全防护策略。通过实际项目案例,帮助开发者构建安全可靠的后端认证体系,提升系统安全性与可扩展能力。

35

2026.03.18

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号