Creando una tierra 3D giratoria

Sé que podemos crear esferas tridimensionales simples utilizando matplotlib , en la documentación se incluye un ejemplo de dicha esfera.

Ahora, también tenemos un método de warp como parte del módulo matplotlib, un ejemplo de su uso está aquí .

Para deformar una imagen cilíndrica a la esfera. ¿Es posible combinar estos métodos para crear una tierra giratoria 3D? A menos que mi forma de pensar acerca de este problema esté muy alejada, parece que para poder hacer esto tendría que tomar los datos de píxeles de la imagen y luego dibujar cada píxel utilizando las expresiones sin y coseno a lo largo de la superficie de la esfera 3D. creado en el primer ejemplo. Algunos ejemplos de estos mapas cilíndricos se pueden encontrar aquí.

Sé que hay formas alternativas de hacerlo a través de maya y blender , pero estoy tratando de mantenerme dentro de matplotlib para hacer esto, ya que quiero crear este gráfico y luego poder trazar datos geoespaciales a la superficie utilizando una serie de datos.

Interesante pregunta. Básicamente intenté seguir el pensamiento descrito por @Skeletor y mapear la imagen para que se pueda mostrar con plot_surface :

 import PIL import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D # load bluemarble with PIL bm = PIL.Image.open('bluemarble.jpg') # it's big, so I'll rescale it, convert to array, and divide by 256 to get RGB values that matplotlib accept bm = np.array(bm.resize([d/5 for d in bm.size]))/256. # coordinates of the image - don't know if this is entirely accurate, but probably close lons = np.linspace(-180, 180, bm.shape[1]) * np.pi/180 lats = np.linspace(-90, 90, bm.shape[0])[::-1] * np.pi/180 # repeat code from one of the examples linked to in the question, except for specifying facecolors: fig = plt.figure() ax = fig.add_subplot(111, projection='3d') x = np.outer(np.cos(lons), np.cos(lats)).T y = np.outer(np.sin(lons), np.cos(lats)).T z = np.outer(np.ones(np.size(lons)), np.sin(lats)).T ax.plot_surface(x, y, z, rstride=4, cstride=4, facecolors = bm) plt.show() 

Resultado: bluemarble.jpg mostrado en 3D con plot_surface

Aquí lo que hice hace unas horas:

Primero importamos las bibliotecas necesarias:

 from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt import imageio 

En segundo lugar, hacemos las cifras y las almacenamos como png en nuestro directorio: Tenga en cuenta que escribí el range(0,330,20)

  for i in range(0,330,20): my_map = Basemap(projection='ortho', lat_0=0, lon_0=i, resolution='l', area_thresh=1000.0) my_map.bluemarble() my_map.etopo() name=str(i) path='/path/to/your/directory/'+name plt.savefig(path+'.png') plt.show() plt.clf() plt.cla() plt.close() 

Y finalmente podemos unir todas las imágenes en un GIF animado:

 images = [] for f in range(0,330,20): images.append(imageio.imread("/path/to/your/directory/"+str(f)+".png")) imageio.mimsave('movie.gif', images, duration=0.5) 

y luego disfrutar del resultado: introduzca la descripción de la imagen aquí

Podría imaginar la siguiente solución: con numpy.roll , podría cambiar su matriz una columna (o más) con cada llamada. Por lo tanto, podría cargar su imagen de la superficie de la tierra en una matriz numpy como plantilla y exportar la imagen girada a un jpg. Esto se grafica como se muestra en el ejemplo de deformación.