Tengo una lista de 3 tuplas que representan un conjunto de puntos en el espacio 3D. Quiero trazar una superficie que cubra todos estos puntos.
La plot_surface
función del mplot3d
paquete requiere que los argumentos X, Y y Z sean matrices 2d. ¿Es plot_surface
la función correcta para trazar la superficie y cómo transformo mis datos en el formato requerido?
data = [(x1,y1,z1),(x2,y2,z2),.....,(xn,yn,zn)]
python
numpy
matplotlib
surface
Graddy
fuente
fuente
Respuestas:
Para las superficies es un poco diferente a una lista de 3 tuplas, debe pasar una cuadrícula para el dominio en matrices 2d.
Si todo lo que tiene es una lista de puntos 3D, en lugar de alguna función
f(x, y) -> z
, entonces tendrá un problema porque hay varias formas de triangular esa nube de puntos 3D en una superficie.Aquí hay un ejemplo de superficie lisa:
fuente
f(x,y) -> z
le brinda más información que simplemente usar un enfoque de lista como el que tenía inicialmente el OP?plot_trisurf
lugar. Pero como he mencionado, no es trivial porque necesita triangular la superficie y hay múltiples soluciones. Como ejemplo básico, considere solo los 4 puntos dados por (0, 0, 0.2), (0, 1, 0), (1, 1, 0.2), (1, 0, 0). Visto desde arriba, parece un cuadrado con un ligero pliegue. Pero, ¿a lo largo de qué diagonal se produce el "pliegue"? ¿Es la diagonal "alta" en 0.2 o la diagonal "baja" en 0? ¡Ambas son superficies válidas! Por lo tanto, debe elegir un algoritmo de triangulación antes de tener una solución bien definida.projection='3d'
en la llamadafig.add_subplot
no estará disponible sin esta importación.Puede leer datos directamente desde algún archivo y trazar
Si es necesario, puede pasar vmin y vmax para definir el rango de la barra de colores, p. Ej.
Sección de bonificación
Me preguntaba cómo hacer algunos gráficos interactivos, en este caso con datos artificiales.
fuente
Acabo de encontrarme con este mismo problema. He espaciadas uniformemente los datos que están en 3 arrays 1-D en lugar de las matrices de 2-D que
matplotlib
'splot_surface
necesidades. Mis datos estaban en un,pandas.DataFrame
así que aquí está elmatplotlib.plot_surface
ejemplo con las modificaciones para trazar 3 matrices 1-D.Ese es el ejemplo original. Agregar este siguiente bit crea el mismo gráfico a partir de 3 matrices 1-D.
Aquí están las cifras resultantes:
fuente
Solo para intervenir, Emanuel tenía la respuesta que yo (y probablemente muchos otros) estamos buscando. Si tiene datos dispersos en 3D en 3 matrices separadas, pandas es una ayuda increíble y funciona mucho mejor que las otras opciones. Para desarrollarlo, suponga que x, y, z son algunas variables arbitrarias. En mi caso, estos fueron c, gamma y errores porque estaba probando una máquina de vectores de soporte. Hay muchas opciones posibles para trazar los datos:
Gráfico de estructura alámbrica de los datos
Dispersión 3D de los datos
El código se ve así:
Aquí está el resultado final:
fuente
mira el ejemplo oficial. X, Y y Z son de hecho matrices 2d, numpy.meshgrid () es una forma sencilla de obtener 2d x, y malla de los valores 1d xey.
http://matplotlib.sourceforge.net/mpl_examples/mplot3d/surface3d_demo.py
aquí hay una forma pitónica de convertir sus 3 tuplas en matrices 3 1d.
Aquí está la triangulación (interpolación) de mtaplotlib delaunay, convierte 1d x, y, z en algo compatible (?):
http://matplotlib.sourceforge.net/api/mlab_api.html#matplotlib.mlab.griddata
fuente
En Matlab hice algo similar usando la
delaunay
función enx
,y
solo coords (no enz
), luego graficando contrimesh
otrisurf
, usandoz
como altura.SciPy tiene la clase Delaunay , que se basa en la misma biblioteca QHull subyacente que la de Matlab.
delaunay
función , por lo que debería obtener resultados idénticos.A partir de ahí, debería haber unas pocas líneas de código para convertir este ejemplo de Trazado de polígonos 3D en python-matplotlib en lo que desea lograr, ya que
Delaunay
le brinda la especificación de cada polígono triangular.fuente
ax.plot_trisurf(..)
.Solo para agregar algunas ideas adicionales que pueden ayudar a otros con problemas de tipo de dominio irregular. Para una situación en la que el usuario tiene tres vectores / listas, x, y, z que representan una solución 2D donde z debe trazarse en una cuadrícula rectangular como una superficie, los comentarios 'plot_trisurf ()' de ArtifixR son aplicables. Un ejemplo similar pero con dominio no rectangular es:
El código anterior produce:
Sin embargo, es posible que esto no resuelva todos los problemas, en particular cuando el problema se define en un dominio irregular. Además, en el caso de que el dominio tenga una o más áreas cóncavas, la triangulación delaunay puede resultar en la generación de triángulos espurios en el exterior del dominio. En tales casos, estos triángulos rebeldes deben eliminarse de la triangulación para lograr la representación de superficie correcta. Para estas situaciones, el usuario puede tener que incluir explícitamente el cálculo de triangulación delaunay para que estos triángulos se puedan eliminar mediante programación. En estas circunstancias, el siguiente código podría reemplazar el código de trazado anterior:
A continuación se muestran gráficos de ejemplo que ilustran la solución 1) con triángulos falsos y 2) donde se han eliminado:
Espero que lo anterior pueda ser de ayuda para las personas con situaciones de concavidad en los datos de la solución.
fuente
No es posible crear directamente una superficie 3D utilizando sus datos. Le recomendaría que construya un modelo de interpolación utilizando algunas herramientas como pykridge . El proceso incluirá tres pasos:
pykridge
X
yY
usandomeshgrid
Z
Después de haber creado su cuadrícula y los
Z
valores correspondientes , ahora está listo para comenzarplot_surface
. Tenga en cuenta que, según el tamaño de sus datos, lameshgrid
función puede ejecutarse durante un tiempo. La solución consiste en crear muestras espaciadas uniformemente con los ejesnp.linspace
forX
yY
, luego aplicar la interpolación para inferir losZ
valores necesarios . Si es así, los valores interpolados pueden diferir del originalZ
porqueX
yY
han cambiado.fuente