9 votes

comment faire pivoter une surface 3D dans matplotlib

J'ai écrit un code pour tracer une surface 3D d'un paraboloïde dans matplotlib.

Comment puis-je faire pivoter la figure de façon à ce qu'elle reste en place (c'est-à-dire sans déplacement vertical ou horizontal) mais qu'elle tourne autour de la ligne y = 0 et z = 0 d'un angle thêta (j'ai surligné en vert la ligne autour de laquelle la figure doit tourner). Voici une illustration pour vous aider à visualiser ce que je décris : enter image description here

Par exemple, si l'on fait pivoter la figure autour de la ligne d'un angle de 180 degrés, la figure sera retournée à l'envers, de sorte que le point d'origine sera désormais le point maximal.

Je voudrais également faire pivoter l'axe pour que la carte des couleurs soit conservée. Voici le code pour dessiner la figure :

#parabaloid
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

#creating grid
y = np.linspace(-1,1,1000)
x = np.linspace(-1,1,1000)
x,y = np.meshgrid(x,y)

#set z values
z = x**2+y**2

#label axes
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

#plot figure
ax.plot_surface(x,y,z,linewidth=0, antialiased=False, shade = True, alpha = 0.5)

plt.show()

18voto

Aguy Points 3371

Quelque chose comme ça ?

ax.view_init(-140, 30)

Insérez-le juste avant votre plt.show() commandement.

5voto

Ophir Carmi Points 1457

Suite à mon commentaire :

import mayavi.mlab as mlab
import numpy as np
x,y = np.mgrid[-1:1:0.001, -1:1:0.001]
z = x**2+y**2
s = mlab.mesh(x, y, z)
alpha = 30  # degrees
mlab.view(azimuth=0, elevation=90, roll=-90+alpha)

mlab.show()

enter image description here

ou en suivant la réponse de @Tamas :

#parabaloid
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from math import sin, cos, pi
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

#creating grid
y = np.linspace(-1,1,200)
x = np.linspace(-1,1,200)
x,y = np.meshgrid(x,y)

#set z values
z0 = x**2+y**2

# rotate the samples by pi / 4 radians around y
a = pi / 4
t = np.transpose(np.array([x,y,z0]), (1,2,0))
m = [[cos(a), 0, sin(a)],[0,1,0],[-sin(a), 0, cos(a)]]
x,y,z = np.transpose(np.dot(t, m), (2,0,1))
# or `np.dot(t, m)` instead `t @ m`

#label axes
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

#plot figure
ax.plot_surface(x,y,z,linewidth=0, antialiased=False, shade = True, alpha = 0.5, facecolors=cm.viridis(z0))

plt.show()

enter image description here

4voto

hege_hegedus Points 569

Le mieux que j'ai pu trouver est de faire tourner les données elles-mêmes.

#parabaloid
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from math import sin, cos, pi

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

#creating grid
y = np.linspace(-1,1,200)
x = np.linspace(-1,1,200)
x,y = np.meshgrid(x,y)

#set z values
z = x**2+y**2

# rotate the samples by pi / 4 radians around y
a = pi / 4
t = np.transpose(np.array([x,y,z]), (1,2,0))
m = [[cos(a), 0, sin(a)],[0,1,0],[-sin(a), 0, cos(a)]]
x,y,z = np.transpose(t @ m, (2,0,1))
# or `np.dot(t, m)` instead `t @ m`

#label axes
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

#plot figure
ax.plot_surface(x,y,z,linewidth=0, antialiased=False, shade = True, alpha = 0.5)

plt.show()

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X