Apa tujuan dari meshgrid di Python / NumPy?

303

Bisakah seseorang menjelaskan kepada saya apa tujuan meshgridfungsi di Numpy? Saya tahu itu menciptakan semacam kotak koordinat untuk merencanakan, tetapi saya tidak bisa melihat manfaat langsungnya.

Saya mempelajari "Pembelajaran Mesin Python" dari Sebastian Raschka, dan ia menggunakannya untuk merencanakan batas keputusan. Lihat input 11 di sini .

Saya juga sudah mencoba kode ini dari dokumentasi resmi, tetapi, sekali lagi, hasilnya tidak terlalu masuk akal bagi saya.

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)

Tolong, jika mungkin, tunjukkan juga kepada saya banyak contoh dunia nyata.

HonzaB
sumber

Jawaban:

391

Tujuannya meshgridadalah untuk membuat kotak persegi panjang dari array nilai x dan array nilai y.

Jadi, misalnya, jika kita ingin membuat kisi di mana kita memiliki titik pada setiap nilai integer antara 0 dan 4 di kedua arah x dan y. Untuk membuat kisi persegi panjang, kita membutuhkan setiap kombinasi dari xdan ytitik.

Ini akan menjadi 25 poin, bukan? Jadi jika kita ingin membuat array x dan y untuk semua poin ini, kita bisa melakukan hal berikut.

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

Ini akan menghasilkan berikut xdan ymatriks, sehingga pasangan elemen yang sesuai dalam setiap matriks memberikan koordinat x dan y dari suatu titik dalam kisi.

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

Kami kemudian dapat merencanakan ini untuk memverifikasi bahwa itu adalah kisi:

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

masukkan deskripsi gambar di sini

Jelas, ini menjadi sangat membosankan terutama untuk rentang besar xdan y. Sebaliknya, meshgridsebenarnya dapat menghasilkan ini untuk kita: yang harus kita tentukan adalah unik xdan ynilai.

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

Sekarang, ketika kita menelepon meshgrid, kita mendapatkan output sebelumnya secara otomatis.

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

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

masukkan deskripsi gambar di sini

Pembuatan kisi-kisi persegi panjang ini berguna untuk sejumlah tugas. Dalam contoh yang Anda berikan di pos Anda, itu hanyalah cara untuk mengambil contoh fungsi ( sin(x**2 + y**2) / (x**2 + y**2)) pada rentang nilai untuk xdan y.

Karena fungsi ini telah diambil sampelnya pada kotak persegi panjang, fungsi tersebut sekarang dapat divisualisasikan sebagai "gambar".

masukkan deskripsi gambar di sini

Selain itu, hasilnya sekarang dapat diteruskan ke fungsi yang mengharapkan data pada kotak persegi panjang (yaitu contourf)

Suever
sumber
10
Anda belum menjelaskan nilai pengembalian xxdan yy. Bagian misterius bagi saya adalah mengapa mengembalikan hasil, dan seperti apa hasilnya. Jawaban Hai Phan berguna untuk itu. Saya kira itu melakukan itu untuk kenyamanan, karena plot ingin dua parameter seperti itu.
nealmcb
2
Saya tidak tahu - itu sebabnya saya mencari informasi ini;) Jadi saya tidak mengatakan itu harus mengembalikan sesuatu yang berbeda. Saya hanya memberikan tebakan terbaik saya pada informasi yang hilang bagi mereka yang baru saja membaca jawaban yang diterima. Dan jika Anda suka, saya menyarankan agar jawaban Anda (yang sudah sangat bagus - terima kasih!) Akan sedikit lebih lengkap jika Anda menjelaskan nilai pengembalian (seperti yang Hai lakukan), bagi kita yang masih bingung.
nealmcb
1
Untuk lebih memahami nilai-nilai xx dan yy, pertimbangkan klaim bahwa kode berikut memberi Anda hasil yang sama dengan np.meshgrid:xx = [xvalues for y in yvalues] yy = [[y for x in xvalues] for y in yvalues]
Matt Kleinsmith
1
Jawaban ini membingungkan- Bukankah ilustrasi pertama xdan ymundur Anda? Ketika Anda melakukannya xx, yy = np.meshgrid(np.arange(4), np.arange(4)), itu adalah kebalikan dari apa yang Anda miliki xdan ydi bagian pertama dari jawabannya. Ini cocok dengan urutan output untuk mgrid, tetapi tidak meshgrid. The xxharus meningkat di x-arah, tetapi Anda meningkat ke arah y.
Scott Staniewicz
1
@ScottStaniewicz Terima kasih telah menunjukkan bahwa kami, sekarang yakin bagaimana saya mengacaukan yang ... Diperbarui!
Suever
249

Atas perkenan Microsoft Excel: 

masukkan deskripsi gambar di sini

Sarsaparilla
sumber
6
Bagus. Fwiw, jika Anda menginginkan array 2 x 12 pasangan di tengah:XYpairs = np.vstack([ XX.reshape(-1), YY.reshape(-1) ])
denis
5
dan jika Anda menginginkan array 12 x 2 dari pasangan di tengah:XYpairs = np.dstack([XX, YY]).reshape(-1, 2)
barlaensdoonn
2
Jawaban bagus. Tujuan dari meshgrid adalah membuat kisi-kisi dengan menggunakan koordinat masing-masing redup.
Anak baik
1
Apa yang saya temukan sedikit aneh adalah bahwa nilai x dan y dikembalikan secara terpisah, bukannya sudah digabungkan menjadi satu array. Jika saya ingin mereka dalam satu array, saya harus melakukan:np.vstack([XX.ravel(), YY.ravel()]).T
user3629892
66

Sebenarnya tujuan np.meshgridsudah disebutkan dalam dokumentasi:

np.meshgrid

Kembalikan matriks koordinat dari vektor koordinat.

Buat susunan koordinat ND untuk evaluasi vektor bidang skalar / vektor ND di atas kisi ND, berikan susunan koordinat satu dimensi x1, x2, ..., xn.

Jadi tujuan utamanya adalah untuk membuat matriks koordinat.

Anda mungkin bertanya pada diri sendiri:

Mengapa kita perlu membuat matriks koordinat?

Alasan Anda memerlukan koordinat matriks dengan Python / NumPy adalah bahwa tidak ada hubungan langsung dari koordinat ke nilai, kecuali ketika koordinat Anda mulai dengan nol dan bilangan bulat murni positif. Kemudian Anda bisa menggunakan indeks array sebagai indeks. Namun ketika itu tidak terjadi, Anda harus menyimpan koordinat di samping data Anda. Di situlah grid masuk.

Misalkan data Anda adalah:

1  2  1
2  5  2
1  2  1

Namun, setiap nilai mewakili wilayah lebar 2 kilometer secara horizontal dan 3 kilometer secara vertikal. Misalkan asal Anda adalah sudut kiri atas dan Anda ingin array yang mewakili jarak yang dapat Anda gunakan:

import numpy as np
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)

dimana v adalah:

array([[0, 0, 0],
       [2, 2, 2],
       [4, 4, 4]])

dan H:

array([[0, 3, 6],
       [0, 3, 6],
       [0, 3, 6]])

Jadi jika Anda memiliki dua indeks, katakanlah xdan y(itu sebabnya nilai balik meshgridbiasanya xxatau xsbukan xdalam kasus ini saya pilih hsecara horizontal!) Maka Anda bisa mendapatkan koordinat x titik, koordinat y titik dan nilai pada titik itu dengan menggunakan:

h[x, y]    # horizontal coordinate
v[x, y]    # vertical coordinate
data[x, y]  # value

Itu membuatnya jauh lebih mudah untuk melacak koordinat dan (bahkan lebih penting) Anda dapat meneruskannya ke fungsi yang perlu mengetahui koordinat.

Penjelasan yang sedikit lebih panjang

Namun, np.meshgriditu sendiri tidak sering digunakan secara langsung, sebagian besar hanya menggunakan salah satu objek yang serupanp.mgrid atau np.ogrid. Berikut np.mgridmerupakan sparse=Falsedan np.ogridpara sparse=Truekasus (saya merujuk pada sparseargumen np.meshgrid). Perhatikan bahwa ada perbedaan yang signifikan antara np.meshgriddan np.ogriddan np.mgrid: Dua nilai pertama yang dikembalikan (jika ada dua atau lebih) dibalik. Seringkali ini tidak masalah tetapi Anda harus memberikan nama variabel yang bermakna tergantung pada konteksnya.

Sebagai contoh, dalam kasus grid 2D dan matplotlib.pyplot.imshowmasuk akal untuk memberi nama item yang dikembalikan pertama np.meshgrid xdan yang kedua ysementara itu sebaliknya untuk np.mgriddan np.ogrid.

np.ogrid dan grid yang jarang

>>> 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]])
       

Seperti yang sudah dikatakan, outputnya terbalik jika dibandingkan dengan np.meshgrid, itu sebabnya saya membukanya sebagai yy, xxganti 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]])

Ini sudah terlihat seperti koordinat, khususnya garis x dan y untuk plot 2D.

Divisualisasikan:

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")

masukkan deskripsi gambar di sini

np.mgrid dan grid padat / disempurnakan

>>> 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]])
       

Hal yang sama berlaku di sini: Output dibalik dibandingkan dengan 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]])
       

Berbeda dengan ogridarray ini mengandung semua xx dan yykoordinat di -5 <= xx <= 5; -5 <= yy <= 5 kisi.

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")

masukkan deskripsi gambar di sini

Kegunaan

Ini tidak hanya terbatas pada 2D, fungsi-fungsi ini berfungsi untuk dimensi arbitrer (well, ada jumlah maksimum argumen yang diberikan untuk berfungsi dalam Python dan jumlah maksimum dimensi yang memungkinkan NumPy memungkinkan):

>>> 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.

Bahkan jika ini juga bekerja untuk 1D ada dua (1 lebih banyak) fungsi pembuatan grid 1D:

Selain startdan stopargumen itu juga mendukung stepargumen (bahkan langkah-langkah rumit yang mewakili jumlah langkah):

>>> 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.]])
       

Aplikasi

Anda secara khusus bertanya tentang tujuan dan pada kenyataannya, kisi-kisi ini sangat berguna jika Anda memerlukan sistem koordinat.

Misalnya jika Anda memiliki fungsi NumPy yang menghitung jarak dalam dua dimensi:

def distance_2d(x_point, y_point, x, y):
    return np.hypot(x-x_point, y-y_point)
    

Dan Anda ingin tahu jarak setiap titik:

>>> 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]])
        

Outputnya akan sama jika seseorang lewat di grid padat bukannya grid terbuka. Penyiaran NumPys memungkinkan!

Mari kita visualisasikan hasilnya:

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()

masukkan deskripsi gambar di sini

Dan ini juga saat NumPys mgriddan ogridmenjadi sangat nyaman karena memungkinkan Anda untuk dengan mudah mengubah resolusi grid Anda:

ys, xs = np.ogrid[-5:5:200j, -5:5:200j]
# otherwise same code as above

masukkan deskripsi gambar di sini

Namun, karena imshowtidak mendukung xdan yinput, Anda harus mengubah kutu dengan tangan. Akan sangat nyaman jika akan menerima xdany mengoordinasikan, kan?

Sangat mudah untuk menulis fungsi dengan NumPy yang secara alami berurusan dengan kisi. Selain itu, ada beberapa fungsi di NumPy, SciPy, matplotlib yang mengharapkan Anda untuk lulus dalam grid.

Saya suka gambar jadi mari kita jelajahi 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)

masukkan deskripsi gambar di sini

Perhatikan bagaimana koordinat sudah diatur dengan benar! Itu tidak akan terjadi jika Anda baru saja lewat di density.

Atau untuk memberikan contoh lain yang menyenangkan menggunakan model astropi (kali ini saya tidak terlalu peduli dengan koordinat, saya hanya menggunakannya untuk membuat beberapa kotak):

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)
    

masukkan deskripsi gambar di sini

Meskipun itu hanya "untuk penampilan" beberapa fungsi yang berkaitan dengan model fungsional dan pemasangan (misalnya scipy.interpolate.interp2d, scipy.interpolate.griddatabahkan menunjukkan contoh menggunakan np.mgrid) dalam Scipy, dll memerlukan grid. Sebagian besar bekerja dengan grid terbuka dan grid padat, namun beberapa hanya bekerja dengan salah satunya.

MSeifert
sumber
Saya hanya ingin mengucapkan terima kasih banyak atas jawaban yang sangat rinci ini. Ini membuat hari saya.
Jlanger
Sungguh cara yang indah untuk menjawab pertanyaan .... begitu rinci. Terima kasih
Bipin
h, v = np.meshgrid(np.arange(3)*3, np.arange(3)*2)- karena 2 km horizontal dan 3km vertikal, bukankah rentang pertama dikalikan 2 dan kedua dengan 3?
Nixt
@Nixt Sayangnya tidak sesederhana itu. Saya mungkin harus memeriksa bagian jawaban itu lagi. Ini adalah trade-off antara tampilan transposed dari matriks dan pengindeksan terbalik - biasanya Anda mengharapkan indeks pertama horisontal dan vertikal kedua tetapi kemudian tampilan akan ditransformasikan. Namun ini sebagian besar detail yang diharapkan tidak membatalkan esensi dari jawaban yang bertujuan untuk mengilustrasikan alasan grid. Tetapi saya akan mencoba merevisinya di masa mendatang.
MSeifert
36

Misalkan Anda memiliki fungsi:

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

dan Anda ingin, misalnya, untuk melihat seperti apa dalam rentang 0 hingga 2 * pi. Bagaimana Anda melakukannya? Ada np.meshgriddatang dalam:

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

dan plot seperti itu akan terlihat seperti:

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

masukkan deskripsi gambar di sini

Begitu np.meshgridjuga kenyamanan. Pada prinsipnya hal yang sama dapat dilakukan oleh:

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

tetapi di sana Anda perlu menyadari dimensi Anda (misalkan Anda memiliki lebih dari dua ...) dan penyiaran yang tepat. np.meshgridmelakukan semua ini untukmu.

Juga meshgrid memungkinkan Anda untuk menghapus koordinat bersama dengan data jika Anda, misalnya, ingin melakukan interpolasi tetapi mengecualikan nilai-nilai tertentu:

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

jadi bagaimana Anda melakukan interpolasi sekarang? Anda dapat memberi xdan yke fungsi interpolasi seperti scipy.interpolate.interp2dsehingga Anda perlu cara untuk mengetahui koordinat mana yang dihapus:

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

dan kemudian Anda masih dapat menginterpolasi dengan koordinat "benar" (coba tanpa meshgrid dan Anda akan memiliki banyak kode tambahan):

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

dan meshgrid asli memungkinkan Anda untuk mendapatkan interpolasi di grid asli lagi:

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

Ini hanya beberapa contoh di mana saya menggunakan meshgridmungkin ada lebih banyak.

MSeifert
sumber
1
Terima kasih atas jawaban Anda! Saat membingungkan yang paling bagi saya adalah kembali nilai-nilai xx, yy. Sulit untuk memahami apa itu dan mengapa kami menggunakannya untuk menghitung fungsinya. Sepertinya, saya mengerti. Kami ingin menghitung beberapa fungsi berdasarkan koordinat. Kita dapat menulis sesuatu seperti ini: for x=1:10: for y=1:10: z[x,y]=sin(x)+sin(y)Sebaliknya kita menghitung zdengan cara yang berbeda z=sin([x,x,...,x]) + sin([y,y,..y]). Perbaiki saya jika saya salah!
Alena Kastsiukavets
Ini bukan 100% kode semu yang benar, tapi saya harap Anda mengerti maksud saya)
Alena Kastsiukavets
Sebenarnya Anda selalu membutuhkan loop ganda (kode pertama Anda). Tetapi ada berbagai cara untuk numpymengarsipkannya dengan : meshgrid atau broadcasting. Jika Anda tidak membuang poin (lihat bagian terakhir dari jawaban saya) keduanya sebenarnya setara secara fungsional. Penyiaran hanyalah sebuah loop implisit melintasi dimensi yang akan disiarkan. Perhatikan bahwa saya menggunakan [:,None]dan [None, :]memasukkan dimensi ekstra sehingga hasilnya disiarkan dengan benar. Contoh kedua Anda lebih seperti:sin([[y],[y],..[y]])
MSeifert
Ilustrasi yang sangat bagus. Terima kasih telah melakukan banyak upaya.
natersoz
interpolated_grid = interpolated(xx, yy)- ini tidak bekerja untuk saya, kesalahan:x and y should both be 1-D arrays
Nixt
4

meshgrid membantu dalam membuat kotak persegi panjang dari dua array 1-D dari semua pasangan titik dari dua array.

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

Sekarang, jika Anda telah mendefinisikan fungsi f (x, y) dan Anda ingin menerapkan fungsi ini ke semua kemungkinan kombinasi titik dari array 'x' dan 'y', maka Anda dapat melakukan ini:

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

Katakanlah, jika fungsi Anda hanya menghasilkan produk dari dua elemen, maka ini adalah bagaimana produk kartesius dapat dicapai, secara efisien untuk array besar.

Dirujuk dari sini

Narasimhan
sumber
1

Ide dasar

Diberi kemungkinan nilai x xs,, (anggap sebagai tanda centang pada sumbu x plot) dan nilai y yang mungkin ys,, meshgridmenghasilkan himpunan titik (x, y) grid yang sesuai --- dianalogikan dengan set((x, y) for x in xs for y in yx). Misalnya, jika xs=[1,2,3]dan ys=[4,5,6], kami akan mendapatkan set koordinat {(1,4), (2,4), (3,4), (1,5), (2,5), (3,5), (1,6), (2,6), (3,6)}.

Bentuk Nilai Pengembalian

Namun, representasi yang meshgridmengembalikan berbeda dari ekspresi di atas dalam dua cara:

Pertama , meshgridmenjabarkan titik-titik grid dalam array 2d: baris sesuai dengan nilai y yang berbeda, kolom sesuai dengan nilai x yang berbeda --- seperti pada list(list((x, y) for x in xs) for y in ys), yang akan memberikan array berikut:

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

Kedua , meshgridmengembalikan koordinat x dan y secara terpisah (yaitu dalam dua array 2d numpy berbeda):

   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

Catatan, np.meshgridjuga bisa menghasilkan grid untuk dimensi yang lebih tinggi. Diberi xs, ys, dan zs, Anda akan mendapatkan kembali xcoords, ycoords, zcoords sebagai array 3d. meshgridjuga mendukung urutan terbalik dari dimensi serta representasi hasil yang jarang.

Aplikasi

Mengapa kita menginginkan bentuk keluaran ini?

Menerapkan fungsi di setiap titik di grid: Salah satu motivasi adalah bahwa operator biner seperti (+, -, *, /, **) kelebihan beban untuk array numpy sebagai operasi elementwise. Ini berarti bahwa jika saya memiliki fungsi def f(x, y): return (x - y) ** 2yang bekerja pada dua skalar, saya juga dapat menerapkannya pada dua array numpy untuk mendapatkan array hasil elementwise: misalnya f(xcoords, ycoords)atau f(*np.meshgrid(xs, ys))memberikan yang berikut pada contoh di atas:

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

Produk luar dimensi yang lebih tinggi: Saya tidak yakin seberapa efisien ini, tetapi Anda bisa mendapatkan produk luar dimensi tinggi dengan cara ini:np.prod(np.meshgrid([1,2,3], [1,2], [1,2,3,4]), axis=0) .

Plot kontur di matplotlib: Saya menemukan meshgridketika menyelidiki menggambar plot kontur dengan matplotlib untuk merencanakan batas keputusan . Untuk ini, Anda menghasilkan kisi dengan meshgrid, mengevaluasi fungsi pada setiap titik kisi (misalnya seperti yang ditunjukkan di atas), dan kemudian meneruskan xcoords, ycoords, dan nilai-f yang dihitung (yaitu zcoords) ke dalam fungsi contourf.

pengguna3780389
sumber