2015-05-15 10 views
12

So che è possibile creare sfere tridimensionali semplici utilizzando matplotlib, un esempio di tale sfera è incluso nello documentation.Creazione di una terra 3D ruotabile

Ora, abbiamo anche un metodo warp come parte del modulo matplotlib, un esempio del suo utilizzo è here.

Per deformare un'immagine cilindrica alla sfera. È possibile combinare questi metodi per creare una terra rotante 3D? A meno che il mio modo di pensare a questo problema sia lontano, sembra che per poterlo fare dovresti prendere i dati dei pixel dell'immagine e poi tracciare ogni pixel usando le espressioni di sin e coseno lungo la superficie della sfera 3D essendo creato nel primo esempio. Alcuni esempi di queste mappe cilindriche possono essere trovati here

so modi alternativi per fare questo sono attraverso maya e blender, ma sto cercando di rimanere all'interno matplotlib per fare questo, come voglio per creare questa trama e quindi in grado per tracciare i dati geospaziali sulla superficie utilizzando una serie di dati.

risposta

7

Interessante domanda. Ho cercato di seguire in sostanza il pensiero delineato da @Skeletor, e mappare l'immagine in modo che si può dimostrare 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() 

Risultato: bluemarble.jpg shown in 3D with plot_surface

0

Posso immaginare la seguente soluzione: Utilizzando numpy.roll è possibile spostare l'array di una colonna (o più) con ogni chiamata. Quindi puoi caricare la tua immagine della superficie terrestre in una matrice numpy come modello ed esportare l'immagine ruotata in un jpg. Questo diagramma come mostrato nell'esempio di warp.

2

Ecco quello che ho fatto alcuni giorni fa:

Per prima cosa importare le librerie necessarie:

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

In secondo luogo, facciamo le figure e memorizzati loro come png nella directory: nota che ho scritto 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() 

E finalmente possiamo unire tutte le immagini in una GIF animata:

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) 

e poi godersi il risultato: enter image description here

Problemi correlati