matplotlib 如何绘制旋转的3D地球

jmo0nnb3  于 2023-05-01  发布在  其他
关注(0)|答案(3)|浏览(261)

我知道我们可以使用matplotlib创建简单的三维球体,documentation中包含了这样一个球体的示例。
现在,我们还有一个warp方法作为matplotlib模块的一部分,它的用法示例是here
将圆柱形图像扭曲到球体。有没有可能将这些方法结合起来创造出一个3D可旋转的地球?除非我思考这个问题的方式是错的,否则要做到这一点,你必须获取图像的像素数据,然后使用sin和cosine表达式沿着第一个示例中创建的3D球体的表面绘制每个像素。这些柱面Map的一些示例可以在here中找到
我知道其他方法是通过mayablender,但我试图在matplotlib内完成此操作,因为我希望创建此图,然后能够使用数据数组将地理空间数据绘制到表面。

xdnvmnnf

xdnvmnnf1#

有趣的问题。我试着基本上遵循@Skeletor概述的想法,并Map图像,以便它可以用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()

结果:x1c 0d1x

n3h0vuf2

n3h0vuf22#

这是我几个小时前做的:
首先,我们导入所需的库:

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

其次,我们制作这些图,并将它们作为png存储在我们的目录中:注意我写了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()

最后,我们可以将所有图像加入一个动画GIF:

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)

然后享受结果:

gcxthw6b

gcxthw6b3#

我可以想象以下解决方案:使用numpy.roll,你可以在每次调用时将数组移动一列(或更多)。因此,您可以将地球表面的图像加载到numpy数组中作为模板,并将旋转后的图像导出为jpg。您将按照扭曲示例中所示进行绘制。

相关问题