Создание анимации на базовой карте - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь оживить сюжет, который перемещается по моей карте (поле зрения самолета). Мне нужно, чтобы пройти через мои координаты, поэтому я попытался использовать цикл 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 голосов
/ 30 августа 2018

У вашего кода было довольно много проблем. Может быть, я просто перечислю их здесь, и тогда вы сможете задать вопросы, если есть что-то, чего вы не понимаете:

  1. Если фигура еще не открыта, вызов Basemap создаст новую фигуру. Это делает дополнительный вызов на plt.figure() (вид) избыточным. Я обычно звоню plt.figure в любом случае, но до звонка Basemap.
  2. Когда вы используете FuncAnimation, вам не нужно перебирать значения, которые вы хотите анимировать - FuncAnimation делает это для вас. Единственное, что вам нужно предоставить - это функция, которая обновляет текущий график в соответствии с целочисленным аргументом, который FuncAnimation предоставит этой функции. Другими словами, весь цикл for, который вы написали, не подходит.
  3. Звоните plt.show() только один раз. Прямо сейчас вы вызываете его каждый раз, когда пробегаете свой цикл for.
  4. Не вызывайте команду plot каждый раз, когда вы хотите обновить свой график. Если все остальное в вашем коде будет правильным, вы получите много строк вместо одной. Вместо этого обновите данные объекта строки, который возвращается plot. Посмотрите код ниже, как это делается.
  5. Количество предоставленных вами точек данных и количество кадров, которые нужно анимировать, не совпадают (4 против 1000), что означает, что анимация будет работать «пустой» в течение длительного времени.
  6. Большинство указанных вами координат находятся за пределами отображаемой области карты.
  7. Не вызывайте объект Basemap map, даже если они делают это в руководствах. map - зарезервированное слово в питоне. Скорее используйте m или bmap или что-то еще.

Ниже я попытался исправить проблемы с вашим кодом, но он может быть изменен слишком сильно для ваших нужд, поэтому, пожалуйста, спросите, есть ли что-то неясное:

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()
...