有人可以给我解释一下Numpy中meshgrid函数的作用是什么?我知道它会创建某种用于绘制坐标的网格,但是我真的看不到它的直接好处。

我正在研究Sebastian Raschka的“ Python机器学习”,他正在使用它用于绘制决策边界。请参阅此处的输入11。

我也在官方文档中尝试过此代码,但是再次,输出对我而言真的没有意义。

x = np.arange(-5, 5, 1)
y = np.arange(-5, 5, 1)
xx, yy = np.meshgrid(x, y, sparse=True)
z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
h = plt.contourf(x,y,z)


,如果可能的话,还请给我展示很多真实的示例。

#1 楼

meshgrid的目的是从x值数组和y值数组中创建一个矩形网格。

因此,例如,如果我们要创建一个在点处有点的网格在x和y方向上,每个介于0和4之间的整数值。要创建矩形网格,我们需要xy点的每个组合。

这将是25个点,对吗?因此,如果我们想为所有这些点创建x和y数组,则可以执行以下操作。

x[0,0] = 0    y[0,0] = 0
x[0,1] = 1    y[0,1] = 0
x[0,2] = 2    y[0,2] = 0
x[0,3] = 3    y[0,3] = 0
x[0,4] = 4    y[0,4] = 0
x[1,0] = 0    y[1,0] = 1
x[1,1] = 1    y[1,1] = 1
...
x[4,3] = 3    y[4,3] = 4
x[4,4] = 4    y[4,4] = 4


这将导致以下xy矩阵,这样每个矩阵中对应元素的配对就可以给出网格中某个点的x和y坐标。

x =   0 1 2 3 4        y =   0 0 0 0 0
      0 1 2 3 4              1 1 1 1 1
      0 1 2 3 4              2 2 2 2 2
      0 1 2 3 4              3 3 3 3 3
      0 1 2 3 4              4 4 4 4 4


然后我们可以绘制它们来验证它们是一个网格:

plt.plot(x,y, marker='.', color='k', linestyle='none')




显然,这特别繁琐,特别是对于xy的较大范围。相反,meshgrid实际上可以为我们生成此代码:我们只需指定唯一的xy值即可。

xvalues = np.array([0, 1, 2, 3, 4]);
yvalues = np.array([0, 1, 2, 3, 4]);


现在,当我们调用meshgrid时,我们得到自动生成先前的输出。

xx, yy = np.meshgrid(xvalues, yvalues)

plt.plot(xx, yy, marker='.', color='k', linestyle='none')




创建这些矩形网格对于许多任务很有用。在您的帖子中提供的示例中,这只是一种在sin(x**2 + y**2) / (x**2 + y**2)x的值范围内对函数(y)进行采样的方法。

由于已在矩形网格上采样了此函数,因此该函数现在可以可视化为“图像”。


现在可以将结果传递给期望在矩形网格上获得数据的函数(即contourf

评论


您尚未说明返回值xx和yy。对我来说,神秘的部分是为什么它返回那对结果以及它们的外观。海潘的答案很方便。我想这样做是为了方便,因为plot需要这样的两个参数。

–nealmcb
17年4月25日在23:09

我不知道-这就是为什么我要查找此信息;)所以我并不是说它应该返回不同的内容。对于那些刚刚阅读了可接受答案的人,我只是对丢失的信息提供了最好的猜测。而且,如果您愿意,我建议您对我们中仍然感到困惑的那些人来说,如果您解释了返回值(如Hai所做的那样),答案将会更加完整(谢谢!)。

–nealmcb
17年5月10日在15:07



为了更好地理解xx和yy的值,请考虑以下代码与np.meshgrid具有相同的结果:xx = [y值中y的y的x值] yy = [y值中y的x的y] ]

–马特·克莱因史密斯(Matt Kleinsmith)
17-10-15在8:21

这个答案令人困惑-您对x和y的第一个图示不是倒退吗?当您做xx时,yy = np.meshgrid(np.arange(4),np.arange(4)),这与答案第一部分中x和y的含义相反。它匹配mgrid的输出顺序,但不匹配meshgrid。 xx应该在x方向上增加,但是您的x在y方向上增加。

–斯科特·斯坦尼维奇(Scott Staniewicz)
18年7月28日在19:11

@ScottStaniewicz感谢您指出我们的,现在确定我是如何弄乱那个的...更新!

– Suever
18年7月29日在12:36

#2 楼

由Microsoft Excel提供:



评论


真好首先,如果要在中间放置2 x 12的对数组:XYpairs = np.vstack([XX.reshape(-1),YY.reshape(-1)])

–丹尼斯
17 Mar 14 '17 at 18:53

并且如果您想在中间放置12 x 2的对数组:XYpairs = np.dstack([XX,YY])。reshape(-1,2)

– barlaensdoonn
19年1月28日在22:47

好答案。 meshgrid的目的是通过使用每个暗淡的坐标来创建网格。

–好孩子
19年3月30日在5:50

我发现有点奇怪的是,x和y值是分别返回的,而不是已经组合成一个数组。如果我希望将它们放在一个数组中,则需要执行以下操作:np.vstack([XX.ravel(),YY.ravel()])。T

–user3629892
19年7月5日在22:00

#3 楼

实际上,文档中已经提到了np.meshgrid的用途:

np.meshgrid
从坐标矢量返回坐标矩阵。
制作ND坐标数组,以对ND标量/矢量场进行矢量化求值给定一维坐标数组x1,x2,...,xn的ND网格。

所以主要目的是创建坐标矩阵。
您可能只是问自己:
为什么需要创建坐标矩阵?
使用Python / NumPy需要坐标矩阵的原因是,坐标与值之间没有直接关系,除非坐标从零开始并且是纯正整数。然后,您可以仅使用数组的索引作为索引。
但是,如果不是这种情况,则需要以某种方式将坐标存储在数据旁边。
假设您的数据是:
1  2  1
2  5  2
1  2  1

但是,每个值代表一个3 x 2公里的区域(水平x垂直)。假设您的原点是左上角,并且您想要一个表示可以使用的距离的数组:
import numpy as np
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)

其中v是:
array([[0, 0, 0],
       [2, 2, 2],
       [4, 4, 4]])

和h:
array([[0, 3, 6],
       [0, 3, 6],
       [0, 3, 6]])

因此,如果您有两个索引,那么假设xy(这就是为什么meshgrid的返回值通常是xxxs而不是x的原因,在这种情况下,我选择了h来表示水平!),则可以获得x的x坐标。点,点的y坐标和该点的值,方法如下:
h[x, y]    # horizontal coordinate
v[x, y]    # vertical coordinate
data[x, y]  # value

这样可以更轻松地跟踪坐标,并且(更重要的是)可以将它们传递给函数需要知道坐标。
稍​​长一点的解释
但是,np.meshgrid本身并不经常直接使用,大多数人只是使用类似对象np.mgridnp.ogrid之一。
这里np.mgrid代表sparse=False的情况,而np.ogrid代表sparse=True的情况(我指的是sparsenp.meshgrid自变量)。请注意,np.meshgridnp.ogridnp.mgrid之间存在显着差异:返回的前两个值(如果有两个或多个)是相反的。通常这并不重要,但是您应该根据上下文提供有意义的变量名。
例如,在2D网格和matplotlib.pyplot.imshow的情况下,命名第一个返回的np.meshgrid x和第二个返回的y是有意义的而对于np.mgridnp.ogrid来说却是另一种方式。

np.ogrid和稀疏网格
>>> import numpy as np
>>> yy, xx = np.ogrid[-5:6, -5:6]
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5],
       [-4],
       [-3],
       [-2],
       [-1],
       [ 0],
       [ 1],
       [ 2],
       [ 3],
       [ 4],
       [ 5]])
       

如前所述,与np.meshgrid相比,输出是相反的,这就是为什么我将其解压缩为yy, xx而不是xx, yy
>>> xx, yy = np.meshgrid(np.arange(-5, 6), np.arange(-5, 6), sparse=True)
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5],
       [-4],
       [-3],
       [-2],
       [-1],
       [ 0],
       [ 1],
       [ 2],
       [ 3],
       [ 4],
       [ 5]])

这已经看起来像坐标,特别是2D图的x和y线。
可视化:
yy, xx = np.ogrid[-5:6, -5:6]
plt.figure()
plt.title('ogrid (sparse meshgrid)')
plt.grid()
plt.xticks(xx.ravel())
plt.yticks(yy.ravel())
plt.scatter(xx, np.zeros_like(xx), color="blue", marker="*")
plt.scatter(np.zeros_like(yy), yy, color="red", marker="x")



np.mgrid和密集/有肉感的网格
>>> yy, xx = np.mgrid[-5:6, -5:6]
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
       [-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
       [-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
       [-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
       [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
       [ 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2],
       [ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3],
       [ 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4],
       [ 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5]])
       

在这里同样适用:与np.meshgrid相比,输出是相反的:
>>> xx, yy = np.meshgrid(np.arange(-5, 6), np.arange(-5, 6))
>>> xx
array([[-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5],
       [-5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5]])
>>> yy
array([[-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5],
       [-4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4],
       [-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3],
       [-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2],
       [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1],
       [ 2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2],
       [ 3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3],
       [ 4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4],
       [ 5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5]])
       

ogrid不同在-5 <= xx <= 5中包含所有xxyy坐标; -5 <= yy <= 5格。
yy, xx = np.mgrid[-5:6, -5:6]
plt.figure()
plt.title('mgrid (dense meshgrid)')
plt.grid()
plt.xticks(xx[0])
plt.yticks(yy[:, 0])
plt.scatter(xx, yy, color="red", marker="x")


功能
它不仅限于二维,而且这些函数适用于任意尺寸(嗯,最大数量Python中赋予函数的参数以及NumPy允许的最大尺寸数):
>>> x1, x2, x3, x4 = np.ogrid[:3, 1:4, 2:5, 3:6]
>>> for i, x in enumerate([x1, x2, x3, x4]):
...     print('x{}'.format(i+1))
...     print(repr(x))
x1
array([[[[0]]],


       [[[1]]],


       [[[2]]]])
x2
array([[[[1]],

        [[2]],

        [[3]]]])
x3
array([[[[2],
         [3],
         [4]]]])
x4
array([[[[3, 4, 5]]]])

>>> # equivalent meshgrid output, note how the first two arguments are reversed and the unpacking
>>> x2, x1, x3, x4 = np.meshgrid(np.arange(1,4), np.arange(3), np.arange(2, 5), np.arange(3, 6), sparse=True)
>>> for i, x in enumerate([x1, x2, x3, x4]):
...     print('x{}'.format(i+1))
...     print(repr(x))
# Identical output so it's omitted here.

即使这些参数也适用于1D,也有两个(更常见的)1D网格创建函数:

np.arange
np.linspace

除了startstop参数外,它还支持step参数(即使复杂的步数也代表了步数):
>>> x1, x2 = np.mgrid[1:10:2, 1:10:4j]
>>> x1  # The dimension with the explicit step width of 2
array([[1., 1., 1., 1.],
       [3., 3., 3., 3.],
       [5., 5., 5., 5.],
       [7., 7., 7., 7.],
       [9., 9., 9., 9.]])
>>> x2  # The dimension with the "number of steps"
array([[ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.],
       [ 1.,  4.,  7., 10.]])
       

应用程序
您专门询问了目的,实际上,如果需要坐标系,这些网格将非常有用。
例如,如果您有一个NumPy函数可以在两个维度上计算距离:
def distance_2d(x_point, y_point, x, y):
    return np.hypot(x-x_point, y-y_point)
    

并且您想知道每个点的距离:
>>> ys, xs = np.ogrid[-5:5, -5:5]
>>> distances = distance_2d(1, 2, xs, ys)  # distance to point (1, 2)
>>> distances
array([[9.21954446, 8.60232527, 8.06225775, 7.61577311, 7.28010989,
        7.07106781, 7.        , 7.07106781, 7.28010989, 7.61577311],
       [8.48528137, 7.81024968, 7.21110255, 6.70820393, 6.32455532,
        6.08276253, 6.        , 6.08276253, 6.32455532, 6.70820393],
       [7.81024968, 7.07106781, 6.40312424, 5.83095189, 5.38516481,
        5.09901951, 5.        , 5.09901951, 5.38516481, 5.83095189],
       [7.21110255, 6.40312424, 5.65685425, 5.        , 4.47213595,
        4.12310563, 4.        , 4.12310563, 4.47213595, 5.        ],
       [6.70820393, 5.83095189, 5.        , 4.24264069, 3.60555128,
        3.16227766, 3.        , 3.16227766, 3.60555128, 4.24264069],
       [6.32455532, 5.38516481, 4.47213595, 3.60555128, 2.82842712,
        2.23606798, 2.        , 2.23606798, 2.82842712, 3.60555128],
       [6.08276253, 5.09901951, 4.12310563, 3.16227766, 2.23606798,
        1.41421356, 1.        , 1.41421356, 2.23606798, 3.16227766],
       [6.        , 5.        , 4.        , 3.        , 2.        ,
        1.        , 0.        , 1.        , 2.        , 3.        ],
       [6.08276253, 5.09901951, 4.12310563, 3.16227766, 2.23606798,
        1.41421356, 1.        , 1.41421356, 2.23606798, 3.16227766],
       [6.32455532, 5.38516481, 4.47213595, 3.60555128, 2.82842712,
        2.23606798, 2.        , 2.23606798, 2.82842712, 3.60555128]])
        

如果通过密集网格而不是开放网格,则输出将相同。 NumPys广播使之成为可能!
让我们可视化结果:
plt.figure()
plt.title('distance to point (1, 2)')
plt.imshow(distances, origin='lower', interpolation="none")
plt.xticks(np.arange(xs.shape[1]), xs.ravel())  # need to set the ticks manually
plt.yticks(np.arange(ys.shape[0]), ys.ravel())
plt.colorbar()


这也是NumPys mgridogrid变得非常方便的时候,因为它使您可以轻松更改分辨率您的网格中的一个:
ys, xs = np.ogrid[-5:5:200j, -5:5:200j]
# otherwise same code as above


但是,由于imshow不支持xy输入,因此必须手动更改刻度。如果接受xy坐标会非常方便,对吗?
用NumPy编写自然处理网格的函数很容易。此外,NumPy,SciPy,matplotlib中还有一些函数希望您通过网格。
我喜欢图像,因此让我们来探索matplotlib.pyplot.contour
ys, xs = np.mgrid[-5:5:200j, -5:5:200j]
density = np.sin(ys)-np.cos(xs)
plt.figure()
plt.contour(xs, ys, density)


请注意如何坐标已正确设置!如果您只是传入density,情况就不会如此。
或者使用天体模型给出另一个有趣的示例(这次我不太在意坐标,我只是使用它们来创建一些网格) :
from astropy.modeling import models
z = np.zeros((100, 100))
y, x = np.mgrid[0:100, 0:100]
for _ in range(10):
    g2d = models.Gaussian2D(amplitude=100, 
                           x_mean=np.random.randint(0, 100), 
                           y_mean=np.random.randint(0, 100), 
                           x_stddev=3, 
                           y_stddev=3)
    z += g2d(x, y)
    a2d = models.AiryDisk2D(amplitude=70, 
                            x_0=np.random.randint(0, 100), 
                            y_0=np.random.randint(0, 100), 
                            radius=5)
    z += a2d(x, y)
    


尽管在Scipy中只是“外观”与功能模型和拟合相关的几个功能(例如scipy.interpolate.interp2d
scipy.interpolate.griddata甚至显示了使用np.mgrid的示例),等需要网格。其中大多数都适用于开放式网格和密集型网格,但是有些仅适用于其中之一。

评论


我只想对这个非常详细的答案表示由衷的感谢。这让我很快乐。

–朗格
20年4月6日在9:46

如此美妙的回答问题的方式...如此详细。谢谢

– Bipin
20年4月23日在7:25

h,v = np.meshgrid(np.arange(3)* 3,np.arange(3)* 2)-由于其水平2公里和垂直3公里,难道第一个范围不应乘以2,第二个范围应乘以3吗?

– Nixt
20 Jun 8'在4:24



@Nixt不幸的是,事情并非如此简单。我可能不得不再次检查答案的那一部分。这是在矩阵的转置显示和反向索引之间进行权衡的方法-通常,您希望第一个索引为水平,第二个为垂直,但随后会进行转置。但是,这主要是一个细节,希望不会使旨在说明网格原因的答案的实质无效。但是,我会在以后的日期尝试进行修改。

–MSeifert
20年6月8日在14:28

@MSeifert我实际上发现numpy的文档简明扼要。当我第一次阅读网状网格时,我问自己:“坐标矩阵是什么?”对于外行人来说,这毫无意义。不过,您的解释很有道理。我希望numpy文档以“愚蠢”的解释开始,然后转向更具技术性的解释。我理解数学的目的是尽可能明确,numpy遵循得很好,但是这是以理解为代价的,并且感觉完全是非Python的。

– A.亨德利
20 Sep 15'4:52



#4 楼

假设您有一个函数:

def sinus2d(x, y):
    return np.sin(x) + np.sin(y)


,例如,您想查看它在0到2 * pi范围内的样子。你会怎么做? np.meshgrid出现在以下位置:

xx, yy = np.meshgrid(np.linspace(0,2*np.pi,100), np.linspace(0,2*np.pi,100))
z = sinus2d(xx, yy) # Create the image on this grid


这样的图看起来像:

import matplotlib.pyplot as plt
plt.imshow(z, origin='lower', interpolation='none')
plt.show()




np.meshgrid只是一个方便。原则上,可以通过以下方式完成此操作:

z2 = sinus2d(np.linspace(0,2*np.pi,100)[:,None], np.linspace(0,2*np.pi,100)[None,:])


,但是您需要了解尺寸(假设您有两个以上...)并且正确广播。 np.meshgrid为您完成所有这些操作。

如果您想进行插值但排除某些值,例如,meshgrid允许您删除坐标和数据,例如:

condition = z>0.6
z_new = z[condition] # This will make your array 1D


那么您现在将如何进行插值?您可以将xy赋予类似scipy.interpolate.interp2d的插值函数,因此您需要一种方法来知道删除了哪些坐标:

x_new = xx[condition]
y_new = yy[condition]


,然后您仍可以使用“正确”的坐标(如果没有网状网格,请尝试一下,您将获得很多额外的代码):

from scipy.interpolate import interp2d
interpolated = interp2d(x_new, y_new, z_new)


,原始的网格可以让您在原始网格上进行插值再次网格:

interpolated_grid = interpolated(xx[0], yy[:, 0]).reshape(xx.shape)


这些只是我使用meshgrid的一些示例,可能还有更多。

评论


谢谢您的回答!对我而言,最令人困惑的时刻是返回值xx,yy。很难理解它们是什么以及为什么我们使用它们来计算函数。似乎,我明白了。我们要基于坐标计算一些函数。我们可以这样写:对于x = 1:10:对于y = 1:10:z [x,y] = sin(x)+ sin(y)相反,我们以不同的方式计算z z = sin([ x,x,...,x])+ sin([y,y,.. y])。如果我错了,请纠正我!

– Alena Kastsiukavets
16-11-20在12:22



这不是100%正确的伪代码,但我希望你明白我的意思)

– Alena Kastsiukavets
16-11-20在12:31

实际上,您始终需要双循环(您的第一个代码)。但是有多种方法可以用numpy对其进行归档:meshgrid或广播。如果您不丢弃点(请参阅我的答案的最后一部分),则两者实际上在功能上是等效的。广播只是要广播的维度上的隐式循环。请注意,我使用了[:,None]和[None,:]来包含额外的尺寸,因此结果可以正确广播。您的第二个示例更像:sin([[y],[y],.. [y]])

–MSeifert
16年11月20日在14:46

一个非常好的插图。感谢您的付出。

–natersoz
20-05-21在3:14

interpolated_grid = interpolated(xx,yy)-这对我不起作用,错误:x和y都应为一维数组

– Nixt
20年6月8日在5:30

#5 楼

meshgrid可帮助从两个数组的所有成对点的两个一维数组中创建一个矩形网格。

x = np.array([0, 1, 2, 3, 4])
y = np.array([0, 1, 2, 3, 4])


现在,如果您定义了函数f( x,y),并且您想将此功能应用于数组“ x”和“ y”中所有可能的点组合,则可以执行以下操作:

f(*np.meshgrid(x, y))


说,如果您的函数仅产生两个元素的乘积,则可以有效地实现大型数组的笛卡尔乘积。

此处引用

#6 楼

简短答案
meshgrid的目的是通过C NumPy库中的矢量化操作来帮助替换Python循环(缓慢的解释代码)。
从此站点获得。

x = np.arange(-4, 4, 0.25)
y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(x, y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

meshgrid用于创建在-4和+4之间的坐标对,在X和Y的每个方向上的增量为.25。然后,每对坐标用于从中找到R和Z。这种准备坐标的“网格”的方法经常用于绘制3D曲面或为2D曲面着色。

详细信息:Python for循环与NumPy矢量操作
更简单例如,假设我们有两个值序列,
a = [2,7,9,20]    
b = [1,6,7,9]    ​

,我们想对每个可能的值对执行一个操作,一个取自第一个列表,一个取自第二个列表。我们还想存储结果。例如,假设我们要获取每个可能的对的值之和。
缓慢而费力的方法
c = []    
for i in range(len(b)):    
    row = []    
    for j in range(len(a)):    
        row.append (a[j] + b[i])
    c.append (row)    
print (c)

结果:
[[3, 8, 10, 21],
 [8, 13, 15, 26],
 [9, 14, 16, 27],
 [11, 16, 18, 29]]

Python被解释,这些循环的执行速度相对较慢。
快速简便的方法
meshgrid旨在从代码中删除循环。它返回两个数组(下面的i和j),可以将它们组合起来以扫描所有现有的对,如下所示:
i,j = np.meshgrid (a,b)    
c = i + j    
print (c)

结果:
[[ 3  8 10 21]
 [ 8 13 15 26]
 [ 9 14 16 27]
 [11 16 18 29]]

幕后的网格
>由meshgrid准备的两个数组是:
(array([[ 2,  7,  9, 20],
        [ 2,  7,  9, 20],
        [ 2,  7,  9, 20],
        [ 2,  7,  9, 20]]),

 array([[1, 1, 1, 1],
        [6, 6, 6, 6],
        [7, 7, 7, 7],
        [9, 9, 9, 9]]))

这些数组是通过重复提供的值来创建的。一个包含相同行中的值,另一个包含相同列中的其他值。行数和列数由另一个序列中的元素数确定。
因此,由meshgrid创建的两个数组在形状上可用于矢量运算。想象一下页面顶部代码中的x和y序列具有不同数量的元素,无论如何,得到的X和Y数组都是形状兼容的,不需要任何广播。
起源
与许多其他NumPy函数一样,numpy.meshgrid来自MATLAB。因此,您还可以研究MATLAB中的示例以查看正在使用的meshgrid,用于3D绘图的代码在MATLAB中看起来是相同的。

#7 楼

基本思想

给出可能的x值xs(将其视为绘图的x轴上的刻度线)和可能的y值ysmeshgrid生成相应的(x ,y)网格点---与set((x, y) for x in xs for y in yx)类似。例如,如果xs=[1,2,3]ys=[4,5,6],我们将获得一组坐标{(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)}

返回值的形式

但是,meshgrid返回的表示形式与上面的表达式有两种方式:

首先,meshgrid在2d数组中布置网格点:行对应于不同的y值,列对应于不同的x值-如list(list((x, y) for x in xs) for y in ys)所示,将给出以下数组:

   [[(1,4), (2,4), (3,4)],
    [(1,5), (2,5), (3,5)],
    [(1,6), (2,6), (3,6)]]


其次,meshgrid分别返回x和y坐标(即在两个不同的numpy 2d数组中):

   xcoords, ycoords = (
       array([[1, 2, 3],
              [1, 2, 3],
              [1, 2, 3]]),
       array([[4, 4, 4],
              [5, 5, 5],
              [6, 6, 6]]))
   # same thing using np.meshgrid:
   xcoords, ycoords = np.meshgrid([1,2,3], [4,5,6])
   # same thing without meshgrid:
   xcoords = np.array([xs] * len(ys)
   ycoords = np.array([ys] * len(xs)).T


注意,np.meshgrid还可生成更大尺寸的网格。给定xs,ys和zs,您将把xcoords,ycoords,zcoords作为3d数组取回来。 meshgrid还支持尺寸的反向排序以及结果的稀疏表示。

应用程序

为什么要这种形式的输出?

在网格上的每个点上应用一个函数:
一个动机是像(+,-,*,/,**)这样的二进制运算符对于numpy数组作为元素操作进行了重载。这意味着如果我有一个可以在两个标量上使用的函数def f(x, y): return (x - y) ** 2,我也可以将其应用于两个numpy数组以获取一个元素结果数组: f(xcoords, ycoords)f(*np.meshgrid(xs, ys))在上面的示例中给出了以下内容:

array([[ 9,  4,  1],
       [16,  9,  4],
       [25, 16,  9]])


高尺寸的外部产品:我不确定这有多有效,但是您可以得到高尺寸这样的外部产品:np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0)

matplotlib中的等高线图:在用matplotlib研究绘图等高线图以绘制决策边界时,我遇到了meshgrid。为此,您使用meshgrid生成一个网格,在每个网格点上评估函数(例如,如上所示),然后将xcoords,ycoords和计算出的f值(即zcoords)传递给Contourf函数。