plt.subplots() 中的轴是“numpy.ndarray”对象,没有属性“plot”
Posted
技术标签:
【中文标题】plt.subplots() 中的轴是“numpy.ndarray”对象,没有属性“plot”【英文标题】:Axes from plt.subplots() is a "numpy.ndarray" object and has no attribute "plot" 【发布时间】:2016-10-24 09:08:36 【问题描述】:如果您试图理解错误消息,以下信息可能是多余的。请先阅读the answer @user707650。
使用 MatPlotLib,我想要一个可通用的脚本,可以从我的数据中创建以下内容。
一个包含 a 个子图的窗口,每列有 b 个子图。我希望能够更改 a 和 b 的值。
如果我有 2a 个子图的数据,我想要 2 个窗口,每个窗口都有前面描述的“a 子图按照 b 每列子图排列”。
我绘制的 x 和 y 数据是存储在 np.arrays 中的浮点数,结构如下:
所有图的 x 数据始终相同,长度为 5。
'x_vector': [0.000, 0.005, 0.010, 0.020, 0.030, 0.040]
所有图的 y 数据都存储在 y_vector 中,其中第一个图的数据存储在索引 0 到 5 处。第二个图的数据存储在索引 6 到 5 处11.第三个地块得到12-18,第四个地块得到19-24,依此类推。
对于这个数据集,我总共有 91 个图(即 91*6 = 546 个值存储在 y_vector 中)。
尝试:
import matplotlib.pyplot as plt
# Options:
plots_tot = 14 # Total number of plots. In reality there is going to be 7*13 = 91 plots.
location_of_ydata = 6 # The values for the n:th plot can be found in the y_vector at index 'n*6' through 'n*6 + 6'.
plots_window = 7 # Total number of plots per window.
rows = 2 # Number of rows, i.e. number of subplots per column.
# Calculating number of columns:
prim_cols = plots_window / rows
extra_cols = 0
if plots_window % rows > 0:
extra_cols = 1
cols = prim_cols + extra_cols
print 'cols:', cols
print 'rows:', rows
# Plotting:
n=0
x=0
fig, ax = plt.subplots(rows, cols)
while x <= plots_tot:
ax[x].plot(x_vector, y_vector[n:(n+location_of_ydata)], 'ro')
if x % plots_window == plots_window - 1:
plt.show() # New window for every 7 plots.
n = n+location_of_ydata
x = x+1
我收到以下错误:
cols: 4
rows: 2
Traceback (most recent call last):
File "Script.py", line 222, in <module>
ax[x].plot(x_vector, y_vector[n:(n+location_of_ydata)], 'ro')
AttributeError: 'numpy.ndarray' object has no attribute 'plot'
【问题讨论】:
导入 numpy 并不重要:matplotlib (pyplot) 已经在幕后做到了,因为它是 matplotlib 的主要依赖项。 matplotlib 和 numpy 真的应该在这里一起工作以抛出更好的错误。这是我希望它是 Matlab 的罕见实例之一。 :) 【参考方案1】:如果您通过简单地打印ax
来调试程序,您会很快发现ax
是一个二维数组:一维用于行,一维用于列。
因此,您需要两个索引来索引ax
以检索实际的AxesSubplot
实例,例如:
ax[1,1].plot(...)
如果您想以现在的方式遍历子图,请先展平ax
:
ax = ax.flatten()
现在ax
是一个一维数组。我不知道是先遍历行还是列,但是如果是错误的,请使用转置:
ax = ax.T.flatten()
当然,现在简单地动态创建每个子图更有意义,因为它已经有一个索引,而其他两个数字是固定的:
for x < plots_tot:
ax = plt.subplot(nrows, ncols, x+1)
注意:您有 x <= plots_tot
,但 x
从 0 开始,您将在当前代码中获得一个 IndexError
(在展平数组之后)。 Matplotlib(不幸的是)为子图索引为 1。我更喜欢使用 0 索引变量(Python 风格),只需为子图索引添加 +1
(如上所示)。
【讨论】:
【参考方案2】:这里的问题在于 matplotlib 如何处理子图。只需执行以下操作:
fig, axes = plt.subplots(nrows=1, ncols=2)
for axis in axes:
print(type(axis))
你会得到一个 matplotlib 对象,它实际上是一个一维数组,可以使用单个索引进行遍历,即轴 [0]、轴 [1]...等等。但是如果你这样做了
fig, axes = plt.subplots(nrows=2, ncols=2)
for axis in axes:
print(type(axis))
你会得到一个 numpy ndarray 对象,它实际上是一个 2D 数组,只能使用 2 个索引进行遍历,即axis[0, 0]、axis[1, 0]...等等。因此,请注意如何合并 for 循环以遍历轴对象。
【讨论】:
【参考方案3】:如果您使用 N x 1 图,例如,如果您喜欢fig, ax = plt.subplots(3, 1)
,那么请喜欢ax[plot_count].plot(...)
【讨论】:
【参考方案4】:轴是二维的,而不是一维的,因此您不能使用一个循环进行迭代。你还需要一个循环:
fig,axes=plt.subplots(nrows=2,ncols=2)
plt.tight_layout()
for ho in axes:
for i in ho:
i.plot(a,a**2)
这没有问题,但如果我尝试:
for i in axes:
i.plot(a,a**2)
发生错误。
【讨论】:
以上是关于plt.subplots() 中的轴是“numpy.ndarray”对象,没有属性“plot”的主要内容,如果未能解决你的问题,请参考以下文章
fig, ax = plt.subplots() 中的解包如何为多个子图工作?
Python可视化matplotlib多子图可视化(Multiple Subplots):plt.axes()plt.subplot()plt.subplots()