Creando imágenes de intersección en matplotlib con imshow u otra función

Tengo dos matrices tridimensionales de datos de radar que penetran en el suelo. Cada matriz es básicamente una colección de imágenes 2D de lapso de tiempo, donde el tiempo aumenta a lo largo de la tercera dimensión. Quiero crear un gráfico en 3D que se interseca con una imagen en 2D de cada matriz.

Estoy tratando esencialmente de crear una ttwig de la cerca. Algunos ejemplos de este tipo de gráfico se encuentran en estos sitios: http://sofes.miximages.com/python/seismapper_3d_seismic_color.gif http://sofes.miximages.com/python/ fence.png

Normalmente uso imshow para mostrar individualmente las imágenes 2-D para su análisis. Sin embargo, mi investigación sobre la funcionalidad de imshow sugiere que no funciona con los ejes 3D. ¿Hay alguna forma de evitar esto? ¿O hay otra función de trazado que podría replicar la funcionalidad de imshow pero se puede combinar con ejes 3D?

Si está contento de contemplar el uso de una biblioteca de trazado diferente (es decir, no de matplotlib), entonces podría valer la pena considerar mayavi / tvtk (aunque la curva de aprendizaje es un poco pronunciada). Lo más cercano que he visto a lo que quieres es a los planos de corte escalares en http://wiki.scipy.org/Cookbook/MayaVi/Examples

La mayor parte de la documentación se encuentra en: http://docs.enthought.com/mayavi/mayavi/index.html

Puede haber mejores formas, pero al menos siempre puedes hacer una malla plana y colorearla:

 import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np # create a 21 x 21 vertex mesh xx, yy = np.meshgrid(np.linspace(0,1,21), np.linspace(0,1,21)) # create some dummy data (20 x 20) for the image data = np.random.random((20, 20)) # create vertices for a rotated mesh (3D rotation matrix) X = np.sqrt(1./3) * xx + np.sqrt(1./3) * yy Y = -np.sqrt(1./3) * xx + np.sqrt(1./3) * yy Z = np.sqrt(1./3) * xx - np.sqrt(1./3) * yy # create the figure fig = plt.figure() # show the reference image ax1 = fig.add_subplot(121) ax1.imshow(data, cmap=plt.cm.BrBG, interpolation='nearest', origin='lower', extent=[0,1,0,1]) # show the 3D rotated projection ax2 = fig.add_subplot(122, projection='3d') ax2.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=plt.cm.BrBG(data), shade=False) 

Esto crea:

introduzca la descripción de la imagen aquí

(Tenga en cuenta que no tuve mucho cuidado con la matriz de rotación, tendrá que crear su propia proyección. Podría ser una buena idea utilizar una matriz de rotación real).

Solo tenga en cuenta que hay un pequeño problema con los postes de la cerca y las cercas, es decir, la cuadrícula tiene un vértice más en comparación con el número de parches.


El enfoque anterior no es muy eficiente si tiene imágenes de alta resolución. Ni siquiera puede ser útil con ellos. Luego, la otra posibilidad es usar un backend que admita transformaciones de imagen afines. Desafortunadamente, entonces tendrás que calcular las transformaciones tú mismo. No es terriblemente difícil, pero sigue siendo un poco torpe, y entonces no obtienes una imagen real en 3D que se pueda girar, etc.

Para este enfoque, consulte http://matplotlib.org/examples/api/demo_affine_image.html

Alternativamente, puede usar OpenCV y su función cv2.warpAffine para deformar su imagen antes de mostrarla con imshow . Si rellena el entorno con colores transparentes, puede colocar imágenes en capas para obtener un resultado que se parece al iamge de su ejemplo.


Solo para darte una idea de las posibilidades de plot_surface , traté de deformar a Lena alrededor de un semi-cilindro:

 import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import numpy as np # create a 513 x 513 vertex mesh xx, yy = np.meshgrid(np.linspace(0,1,513), np.linspace(0,1,513)) # create vertices for a rotated mesh (3D rotation matrix) theta = np.pi*xx X = np.cos(theta) Y = np.sin(theta) Z = yy # create the figure fig = plt.figure() # show the 3D rotated projection ax = fig.add_subplot(111, projection='3d') ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=plt.imread('/tmp/lena.jpg')/255., shade=False) 

De hecho, se dobla bien, pero todas las operaciones en la imagen son bastante lentas:

introduzca la descripción de la imagen aquí