Un moyen facile de tracer une dispersion 3D en Python que je peux tourner autour?
-
12-10-2019 - |
Question
Actuellement, je suis en utilisant matplotlib pour tracer une dispersion 3D et alors qu'il fait le travail, je ne peux pas sembler trouver un moyen de le faire pivoter pour mieux voir mes données.
Voici un exemple:
import pylab as p
import mpl_toolkits.mplot3d.axes3d as p3
#data is an ndarray with the necessary data and colors is an ndarray with
#'b', 'g' and 'r' to paint each point according to its class
...
fig=p.figure()
ax = p3.Axes3D(fig)
ax.scatter(data[:,0], data[:,2], data[:,3], c=colors)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
fig.add_axes(ax)
p.show()
Je voudrais une solution qui me permet de le faire pendant le temps d'exécution, mais aussi longtemps que je peux le faire pivoter et il est court / rapide, je suis très bien avec elle.
Voici une comparaison des parcelles produites après l'application d'un PCA à l'ensemble de données iris:
1. mayavi
2. matplotlib
mâyâvi permet de visualiser plus facilement les données, mais Matplotlib semble plus professionnel. Matplotlib est également plus léger.
La solution
Utilisation mayavi , vous pouvez créer un tel complot avec
import enthought.mayavi.mlab as mylab
import numpy as np
x, y, z, value = np.random.random((4, 40))
mylab.points3d(x, y, z, value)
mylab.show()
L'interface graphique permet une rotation via un clic-glisser, et le zoom avant / arrière via un clic-glisser à droite.
Autres conseils
Eh bien, vous devez d'abord définir ce que vous entendez par « voir mes données mieux » ...
Vous pouvez faire pivoter et zoomer sur le terrain à l'aide de la souris, si vous êtes désireux de travailler de manière interactive.
Si vous êtes juste vouloir faire tourner les axes programatically, puis utilisez ax.view_init(elev, azim)
où elev
et azim
sont l'élévation et l'azimut des angles (en degrés) que vous souhaitez voir votre parcelle de.
Vous pouvez utiliser les ax.elev
, ax.azim
et propriétés ax.dist
pour obtenir / régler l'altitude, l'azimut et la distance du point de vue actuel.
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
def randrange(n, vmin, vmax):
return (vmax-vmin)*np.random.rand(n) + vmin
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
n = 100
for c, m, zl, zh in [('r', 'o', -50, -25), ('b', '^', -30, -5)]:
xs = randrange(n, 23, 32)
ys = randrange(n, 0, 100)
zs = randrange(n, zl, zh)
ax.scatter(xs, ys, zs, c=c, marker=m)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.show()
Nous obtenons une belle scatterplot:
Vous pouvez faire pivoter les axes programatically comme indiqué:
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
def randrange(n, vmin, vmax):
return (vmax-vmin)*np.random.rand(n) + vmin
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
n = 100
for c, m, zl, zh in [('r', 'o', -50, -25), ('b', '^', -30, -5)]:
xs = randrange(n, 23, 32)
ys = randrange(n, 0, 100)
zs = randrange(n, zl, zh)
ax.scatter(xs, ys, zs, c=c, marker=m)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
ax.azim = 200
ax.elev = -45
plt.show()
L'espoir qui aide un peu!