在底图上绘制动画

时间:2018-08-29 16:45:43

标签: python for-loop animation matplotlib-basemap

我正在尝试为在我的地图(飞机的视场)上移动的图制作动画。我需要它遍历我的坐标,因此我尝试使用for循环。运行此命令时,我得到两个帧,第一个是空的,第二个只是空的地图。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.basemap import Basemap

#map of Puerto Rico
map=Basemap(projection='merc', llcrnrlat=17.5,urcrnrlat=19.,llcrnrlon=-67.5, urcrnrlon=-65, epsg=4139)
map.arcgisimage(service='World_Shaded_Relief', xpixels = 2000)
plt.title("Flight Path of sbet 0059")

#sample coordinates
lon=[-63,-64,-65,-66]
lon=[int(l) for l in lon]
lat=[17., 17.5, 18., 18.5]
lat=[int(l) for l in lat]
time=[1, 3, 5, 7]
time=[int(l) for l in time]

fig=plt.figure()



for a1,b1 in zip(lon,lat):

    def init():
        fig
        return(fig),

    def animate(i):
        x,y=map(a1,b1)
        map.plot(x,y, linewidth = 1,color = 'm')
        return(map),

    anim=animation.FuncAnimation(fig, animate, frames=len(time), interval=1000)

    plt.show()

有人知道问题出在哪里吗,我怎么知道该图在地图上移动?谢谢!

1 个答案:

答案 0 :(得分:0)

您的代码有很多问题。也许我只是在这里列出它们,然后您可以问一些您是否不了解的问题:

  1. 如果尚未打开任何图形,则对Basemap的调用将生成一个新图形。这使得对plt.figure()(种类)的额外调用变得多余。无论如何,我通常都会打电话给plt.figure,但是在打电话给Basemap之前是
  2. 使用FuncAnimation时,不必遍历要设置动画的值-FuncAnimation正在为您做这件事。您唯一需要提供的是根据FuncAnimation将提供给该函数的整数参数更新当前图的函数。换句话说,您编写的整个for循环是行不通的。
  3. 仅拨打一次plt.show()。现在,您每次在for循环中运行时都调用它。
  4. 每次要更新绘图时都不要调用plot命令。如果代码中的其他所有内容都正确,那么您将获得多行而不是一行。而是更新plot返回的行对象的数据。请参见下面的代码。
  5. 您提供的数据点数量和要设置动画的帧数量不匹配(4对1000),这意味着动画将长时间运行“空”。
  6. 您提供的大多数坐标都在您显示的地图区域之外。
  7. 即使在本教程中也不要调用底图对象mapmap是python中的保留字。宁可使用mbmap之类的东西。

以下,我尝试纠正您的代码中的问题,但可能会因您的需要对其进行过多更改,因此请询问是否存在任何不清楚的地方:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.basemap import Basemap

fig=plt.figure()

#map of Puerto Rico
bmap=Basemap(projection='merc', llcrnrlat=17.5,urcrnrlat=19.,llcrnrlon=-67.5, urcrnrlon=-65, epsg=4139)
bmap.arcgisimage(service='World_Shaded_Relief', xpixels = 2000)
plt.title("Flight Path of sbet 0059")

#sample coordinates
##lon=[-63,-64,-65,-66]
##lon=[int(l) for l in lon]
##lat=[17., 17.5, 18., 18.5]
##lat=[int(l) for l in lat]
##time=[1, 3, 5, 7]
##time=[int(l) for l in time]

#generate the flight coordinates (just a straight line with 100 points)
N = 100
lon = np.linspace(-64, -68, N)
lat = np.linspace(17, 19.5, N)

#only convert the coordinates once    
x,y = bmap(lon, lat)

#generate the original line object with only one point
line, = bmap.plot(x[0], y[0], linewidth = 1, color = 'm')

def animate(i):
    #this is doing all the magic. Every time animate is called, the line
    #will become longer by one point:
    line.set_data(x[:i],y[:i])  
    return line

anim=animation.FuncAnimation(fig, animate, frames=N, interval=N)

plt.show()