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 npnp.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
disons
sur un domaine rectangulaire
la technique standard consiste à
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 pavageappliquer la fonction en question à ces deux tableaux, ce qui donne un tableau rectangulaire avec la valeur de la fonction à ce point
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)Zarray([[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 widgetfig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
surf = ax.plot_surface(X, Y, Z)
plt.show()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**2fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
surf = ax.plot_surface(X2, Y2, Z2)
plt.show()