【问题标题】:Creating a rotatable 3D earth创建一个可旋转的 3D 地球
【发布时间】:2015-07-27 22:40:13
【问题描述】:

我知道我们可以使用 matplotlib 创建简单的 3 维球体,documentation 中包含此类球体的示例。

现在,我们还有一个 warp 方法作为 matplotlib 模块的一部分,它的用法示例是 here

将圆柱图像变形为球体。是否可以结合这些方法来创建一个 3D 可旋转地球?除非我对这个问题的思考方式不正确,否则似乎要能够做到这一点,您必须获取图像的像素数据,然后使用沿 3D 球体表面的正弦和余弦表达式绘制每个像素在第一个示例中创建。这些圆柱图的一些示例可以在here

找到

我知道可以通过mayablender 执行此操作的替代方法,但我试图留在matplotlib 内执行此操作,因为我想创建此图,然后能够将地理空间数据绘制到使用数据数组的表面。

【问题讨论】:

    标签: python python-3.x matplotlib plot 3d


    【解决方案1】:

    这是我几个小时前做的:

    首先我们导入需要的库:

    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)
    

    然后享受结果:

    【讨论】:

      【解决方案2】:

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

      结果:

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 2014-07-18
          • 1970-01-01
          • 1970-01-01
          • 2016-06-28
          • 1970-01-01
          • 2021-07-11
          • 2018-04-18
          • 2021-05-16
          • 1970-01-01
          相关资源
          最近更新 更多