为什么pyplot.contour()要求Z为2D数组?


问题内容

matplotlib.pyplot.contour()函数需要3个输入数组XYZ
数组XY指定点的x坐标和y坐标,而Z指定在点处评估的感兴趣函数的相应值。

我知道,np.meshgrid()这很容易产生用作以下参数的数组contour()

X = np.arange(0,5,0.01)
Y = np.arange(0,3,0.01)

X_grid, Y_grid = np.meshgrid(X,Y)
Z_grid = X_grid**2 + Y_grid**2

plt.contour(X_grid, Y_grid, Z_grid)  # Works fine

这很好。方便地,这也很好:

plt.contour(X, Y, Z_grid)  # Works fine too

但是,为什么 要求Z输入是2D数组? __

为什么即使使用适当对齐的所有相同数据,也不允许以下内容?

plt.contour(X_grid.ravel(), Y_grid.ravel(), Z_grid.ravel())  # Disallowed

另外, 仅指 Z定时(没有对应的XY)的语义是什么?


问题答案:

查看某人的文档contour发现,有两种方法可以调用此函数,例如contour(Z)contour(X,Y,Z)。所以,你会发现它不需要任何X或者Y价值能够体现的。

但是,为了绘制轮廓,函数必须知道下面的网格。Matplotlib的contour基于矩形网格。但即便如此,允许contour(z),与z作为一维数组,就不可能知道现场应该如何绘制。在的情况下contour(Z),其中Z是一个二维数组,它的形状明确地将针对图中的网格。

一旦知道了该网格,是否将可选XY数组展平就变得无关紧要了。实际上,文档告诉我们的是:

X和Y必须都是与Z形状相同的2-D,或者它们都必须是1-D,以使len(X)是Z中的列数,而len(Y)是Z中的行数。

同样显而易见的是,某些东西 plt.contour(X_grid.ravel(), Y_grid.ravel(), Z_grid.ravel())无法生成等高线图,因为有关网格形状的所有信息都将丢失,并且等高线函数无法知道如何解释数据。例如,如果len(Z_grid.ravel()) == 12底层网格的形状可以是(1,12), (2,6), (3,4), (4,3), (6,2), (12,1)

可能的解决方法当然是允许一维数组并引入参数shape,例如plt.contour(x,y,z, shape=(6,2))。但是事实并非如此,因此您必须忍受Z需要为2D的事实。

但是,如果您正在寻找一种方法来获得具有平坦(散乱的)数组的国土图,则可以使用plt.tricontour()

plt.tricontour(X_grid.ravel(), Y_grid.ravel(), Z_grid.ravel())

在这里,将使用Delaunay三角剖分在内部生成三角形网格。因此,即使完全随机化的点也将产生不错的结果,如下图所示,将其与赋予的相同随机点进行比较contour

在此处输入图片说明

(这里是产生这张图片代码