Skip to article frontmatterSkip to article content

La fonction np.meshgrid est intéressante - entre autres - pour dessiner des courbes en 3d

Son fonctionnement est assez similaire à np.indices, mais au lieu de produire des entiers, on va typiquement lui passer des tableaux produits à base de np.linspace.

rappels

import numpy as np
np.indices((5, 10))
array([[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3, 3, 3, 3, 3], [4, 4, 4, 4, 4, 4, 4, 4, 4, 4]], [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]])
np.linspace(-np.pi, np.pi, 10)
array([-3.14159265, -2.44346095, -1.74532925, -1.04719755, -0.34906585, 0.34906585, 1.04719755, 1.74532925, 2.44346095, 3.14159265])

pour dessiner une courbe en 3D

Imaginons qu’on veuille représenter une fonction de R2R\mathbb{R}^2 \rightarrow \mathbb{R}

disons f(x,y)=x2+y2f(x, y) = x^2 + y^2

sur un domaine rectangulaire

la technique standard consiste à

  1. créer deux tableaux X et Y rectangulaires, qui correspondent à notre pavage
    le premier contient les X, et le second contient les Y, des points du pavage

  2. appliquer la fonction en question à ces deux tableaux, ce qui donne un tableau rectangulaire avec la valeur de la fonction à ce point

  3. on peut ensuite passer ces trois tableaux rectangulaires à plt.plot_surface

étape 1: meshgrid

# on commence par calculer les domaines

domX = np.linspace(-5, 5, 5)
domY = np.linspace(0, 9, 10)
# avec meshgrid, c'est magique, ça fabrique le pavage pour nous

X, Y = np.meshgrid(domX, domY)
X, Y
(array([[-5. , -2.5, 0. , 2.5, 5. ], [-5. , -2.5, 0. , 2.5, 5. ], [-5. , -2.5, 0. , 2.5, 5. ], [-5. , -2.5, 0. , 2.5, 5. ], [-5. , -2.5, 0. , 2.5, 5. ], [-5. , -2.5, 0. , 2.5, 5. ], [-5. , -2.5, 0. , 2.5, 5. ], [-5. , -2.5, 0. , 2.5, 5. ], [-5. , -2.5, 0. , 2.5, 5. ], [-5. , -2.5, 0. , 2.5, 5. ]]), array([[0., 0., 0., 0., 0.], [1., 1., 1., 1., 1.], [2., 2., 2., 2., 2.], [3., 3., 3., 3., 3.], [4., 4., 4., 4., 4.], [5., 5., 5., 5., 5.], [6., 6., 6., 6., 6.], [7., 7., 7., 7., 7.], [8., 8., 8., 8., 8.], [9., 9., 9., 9., 9.]]))

on voit bien la ressemblance avec indices, en ce sens que le premier tableau contient la coordonnée et X et le second contient la coordonnée en Y

X.shape, Y.shape
((10, 5), (10, 5))

étape 2: calcul de Z

maintenant on peut appliquer la fonction

Z = X**2 + Y*2
Z.shape
(10, 5)
Z
array([[25. , 6.25, 0. , 6.25, 25. ], [27. , 8.25, 2. , 8.25, 27. ], [29. , 10.25, 4. , 10.25, 29. ], [31. , 12.25, 6. , 12.25, 31. ], [33. , 14.25, 8. , 14.25, 33. ], [35. , 16.25, 10. , 16.25, 35. ], [37. , 18.25, 12. , 18.25, 37. ], [39. , 20.25, 14. , 20.25, 39. ], [41. , 22.25, 16. , 22.25, 41. ], [43. , 24.25, 18. , 24.25, 43. ]])

étape 3: dessin

et la dessiner

import matplotlib.pyplot as plt

%matplotlib widget
fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
surf = ax.plot_surface(X, Y, Z)

plt.show()
Loading...

naturellement dans la vraie vie on construit des domaines avec plus de points, par défaut linspace met 50 points dans l’intervalle

domX2, domY2 = np.linspace(-5, 5), np.linspace(0, 10)
X2, Y2 = np.meshgrid(domX2, domY2)
Z2 = X2**2 + Y2**2
fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
surf = ax.plot_surface(X2, Y2, Z2)

plt.show()
Loading...