J'ai une liste de 3 tuples représentant un ensemble de points dans l'espace 3D. Je veux tracer une surface qui couvre tous ces points.
La plot_surface
fonction du mplot3d
package nécessite que les arguments X, Y et Z soient des tableaux 2d. Est-ce que plot_surface
la bonne fonction pour tracer la surface et comment transformer mes données au format requis?
data = [(x1,y1,z1),(x2,y2,z2),.....,(xn,yn,zn)]
python
numpy
matplotlib
surface
Graddy
la source
la source
Réponses:
Pour les surfaces, c'est un peu différent d'une liste de 3-tuples, vous devriez passer dans une grille pour le domaine dans des tableaux 2D.
Si tout ce que vous avez est une liste de points 3D, plutôt qu'une fonction
f(x, y) -> z
, vous aurez un problème car il existe plusieurs façons de trianguler ce nuage de points 3D en une surface.Voici un exemple de surface lisse:
la source
f(x,y) -> z
vous apporte plus d'informations que la simple utilisation d'une approche de liste comme l'OP avait initialement.plot_trisurf
place. Mais comme je l'ai mentionné, ce n'est pas trivial car vous devez trianguler la surface et il existe plusieurs solutions. À titre d'exemple de base, considérons seulement les 4 points donnés par (0, 0, 0,2), (0, 1, 0), (1, 1, 0,2), (1, 0, 0). Vu d'en haut, il ressemble juste à un carré avec un léger pli. Mais le long de quelle diagonale se produit le «pli»? Est-ce la diagonale «haute» à 0,2 ou la diagonale «basse» à 0? Les deux sont des surfaces valides! Vous devez donc choisir un algorithme de triangulation avant d'avoir une solution bien définie.projection='3d'
dans l'appelfig.add_subplot
ne sera pas disponible sans cette importation.Vous pouvez lire les données directement à partir d'un fichier et d'un tracé
Si nécessaire, vous pouvez passer vmin et vmax pour définir la plage de la barre de couleurs, par exemple
Section bonus
Je me demandais comment faire des tracés interactifs, dans ce cas avec des données artificielles
la source
Je viens de rencontrer ce même problème. J'ai des données uniformément espacées qui sont dans 3 tableaux 1-D au lieu des tableaux 2-D qui
matplotlib
leplot_surface
souhaitent. Mes données se trouvaient dans unpandas.DataFrame
alors voici l'matplotlib.plot_surface
exemple avec les modifications pour tracer 3 tableaux 1-D.C'est l'exemple original. L'ajout de ce bit suivant crée le même tracé à partir de 3 tableaux 1-D.
Voici les chiffres obtenus:
la source
Juste pour intervenir, Emanuel avait la réponse que je (et probablement beaucoup d'autres) recherchaient. Si vous avez des données dispersées en 3D dans 3 tableaux séparés, pandas est une aide incroyable et fonctionne beaucoup mieux que les autres options. Pour élaborer, supposons que vos x, y, z sont des variables arbitraires. Dans mon cas, il s'agissait de c, gamma et erreurs parce que je testais une machine vectorielle de support. Il existe de nombreux choix potentiels pour tracer les données:
Tracé filaire des données
Diffusion 3D des données
Le code ressemble à ceci:
Voici la sortie finale:
la source
consultez l'exemple officiel. X, Y et Z sont en effet des tableaux 2d, numpy.meshgrid () est un moyen simple d'obtenir un maillage 2d x, y à partir des valeurs 1d x et y.
http://matplotlib.sourceforge.net/mpl_examples/mplot3d/surface3d_demo.py
voici un moyen pythonique de convertir vos 3 tuples en 3 tableaux 1d.
Voici la triangulation delaunay mtaplotlib (interpolation), elle convertit 1d x, y, z en quelque chose de conforme (?):
http://matplotlib.sourceforge.net/api/mlab_api.html#matplotlib.mlab.griddata
la source
Dans Matlab, j'ai fait quelque chose de similaire en utilisant la
delaunay
fonction surx
,y
coords uniquement (pas lez
), puis en traçant avectrimesh
outrisurf
, en utilisantz
comme hauteur.SciPy a la classe Delaunay , qui est basée sur la même bibliothèque QHull sous-jacente que le Matlab
delaunay
fonction , vous devriez donc obtenir des résultats identiques.À partir de là, il devrait y avoir quelques lignes de code pour convertir cet exemple de tracé de polygones 3D en python-matplotlib en ce que vous souhaitez atteindre, comme
Delaunay
vous le donne la spécification de chaque polygone triangulaire.la source
ax.plot_trisurf(..)
.Juste pour ajouter quelques réflexions supplémentaires qui peuvent aider les autres avec des problèmes de type de domaine irrégulier. Pour une situation où l'utilisateur dispose de trois vecteurs / listes, x, y, z représentant une solution 2D où z doit être tracé sur une grille rectangulaire comme une surface, les commentaires 'plot_trisurf ()' par ArtifixR sont applicables. Un exemple similaire mais avec un domaine non rectangulaire est:
Le code ci-dessus produit:
Cependant, cela peut ne pas résoudre tous les problèmes, en particulier lorsque le problème est défini sur un domaine irrégulier. De même, dans le cas où le domaine a une ou plusieurs zones concaves, la triangulation de delaunay peut conduire à générer des triangles parasites extérieurs au domaine. Dans de tels cas, ces triangles non fiables doivent être supprimés de la triangulation afin d'obtenir la représentation de surface correcte. Pour ces situations, l'utilisateur peut avoir à inclure explicitement le calcul de triangulation de delaunay afin que ces triangles puissent être supprimés par programme. Dans ces circonstances, le code suivant pourrait remplacer le code de tracé précédent:
Des exemples de graphiques sont donnés ci-dessous, illustrant la solution 1) avec des triangles parasites, et 2) où ils ont été supprimés:
J'espère que ce qui précède peut être utile aux personnes présentant des situations de concavité dans les données de la solution.
la source
Il n'est pas possible de créer directement une surface 3D en utilisant vos données. Je vous recommande de créer un modèle d'interpolation à l'aide de certains outils comme pykridge . Le processus comprendra trois étapes:
pykridge
X
etY
utilisantmeshgrid
Z
Après avoir créé votre grille et les
Z
valeurs correspondantes , vous êtes maintenant prêt à partirplot_surface
. Notez que selon la taille de vos données, lameshgrid
fonction peut s'exécuter pendant un certain temps. La solution de contournement consiste à créer des échantillons régulièrement espacés à l'aidenp.linspace
des axes forX
etY
, puis d'appliquer une interpolation pour déduire lesZ
valeurs nécessaires . Si tel est le cas, les valeurs interpolées peuvent différer de l'originalZ
carX
etY
ont changé.la source