Matplotlib等高线图输入数组顺序

8

问题: Matplotlib期望输入2D数组的轮廓应当是什么顺序?

详细说明: Matplotlib轮廓文档表明该例程的调用为

x_axis = np.linspace(10,100,n_x)
y_axis = np.linspace(10,100,n_y)
matplotlib.pyplot.contour(x_axis, y_axis, scalar_field)

scalar_field必须是一个二维数组。例如,可以通过以下方式生成scalar_field:

scalar_field = np.array( [(x*y) for x in x_axis for y in y_axis])
scalar_field = scalar_field.reshape(n_x, n_y)

如果在等高线函数中给出了 scalar_field 参数,
plt.contour(x_axis, y_axis,scalar_field) #incorrect

图表的方向不正确(旋转)。要恢复正确的方向,必须对标量场进行转置:

plt.contour(x_axis, y_axis,scalar_field.transpose()) #correct

那么,轮廓期望标量场的顺序是什么?
2个回答

8
您应该使用contour绘图时,同时传入2D数组XY。在您的scalar_field数组中的每个点将对应于XY中的一个坐标(x, y)。您可以方便地使用numpy.meshgrid创建XY
import matplotlib.pyplot as plt
import numpy as np

X, Y = np.meshgrid(x_axis, y_axis, copy=False, indexing='xy')
plt.contour(X, Y, scalar_field)    

如果您想让x坐标表示行,y表示列,则可以将参数indexing更改为'ij',但在这种情况下,必须使用ij索引计算scalar_fied


请问您能详细说明一下索引部分和排序吗? - Ivan
@Ivan 当你使用 'xy' 索引时,你可以想象自己从上方查看矩阵,其中 x 坐标从左到右,而 y 坐标从下到上。有时这并不是你想要的,因此你可以选择使用 'ij' 索引,其中第一个索引可以被视为行,第二个索引可以被视为列... - Saullo G. P. Castro

3

x 值应该对应于数据的 ,而不是行(即,x 是水平轴,y 是垂直轴)。你的操作反了,这就是你需要转置 z 值才能使其正常工作的原因。

为避免需要转置,创建数组时,请按以下方式进行:

scalar_field = np.array( [(x*y) for y in y_axis for x in x_axis])
scalar_field = scalar_field.reshape(n_y, n_x)

请问您能否解释一下文档中具体说明了关于 x 和 y 的内容在哪里? - Ivan
contour 的 matplotlib 1.2.1 文档字符串中指出:“XY 必须都是二维数组,形状与 Z 相同,或者它们必须都是一维数组,使得 len(X)Z 的列数,len(Y)Z 的行数。” - bogatron
是的,但这正是我的问题:len(x)是第一个索引,所以reshape必须遵守这一点,因此正确答案是reshape(n_x, n_y),而不是相反。这就是为什么会让人困惑的原因。 - Ivan
你的困惑是可以理解的,这是由于numpy数组寻址和contour使用的matplotlib 2D坐标空间之间的差异造成的。你在reshape调用中没有得到错误,因为numpy会很乐意将你的数组重塑为任何保持元素数量不变的形状。但答案仍然是一样的:你对Z数组进行的第一个索引(由numpy指定)对应于数组的,但传递给contourX数组(由matplotlib指定)应该对应于Z - bogatron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接