2017-02-22 63 views
3

Я создал небольшую программу, которая принимает город НХЛ, а затем рисует путь, который команда путешествует в течение всего сезона.Как анимировать функцию matrotlib drawgreatcircle?

В результате графический грязен:

Messy Graphic

Так что я пришла в голову мысль, что было бы интересно, если бы я анимированный траектории полета, вроде как смотреть фильм Индиана Джонс, где линия растет из один пункт к другому.

Мое понимание взгляда на другие образцы matplotlib заключается в том, что функция анимации принимает функцию, вычисляет ее вывод и затем обновляет графику. Я не вижу, как это возможно с drawgreatcircle, так как всякий раз, когда я его называю, мне дается завершенная строка.

Любая идея о том, как я могу подойти к этому?

Вот пример изображения из примера кода ниже

Sample Image

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

fig = plt.figure(figsize=(10, 10)) 
m = Basemap(projection='merc', resolution=None, 
        llcrnrlon=-125, llcrnrlat=25, # LL = lower left 
        urcrnrlon=-60, urcrnrlat=55) #UR = upper right 
m.etopo(scale=0.5, alpha=0.5) 


# Ottawa to Anaheim 
# Ottawa 
lat1 = 45.4215 
lon1 = -75.6972 

# Anaheim 
lat2 = 33.8353 
lon2 = -117.9145 

m.drawgreatcircle(lon1,lat1,lon2,lat2) 
+0

, если вы не заботитесь слишком много о математике тонкостей, то просто линейная интерполяция в широта, долгота должна выглядеть хорошо, если вы избегаете полюсов – f5r5e5d

+0

Что такое линейная интерполяция? –

+0

Что такое город НХЛ? – ImportanceOfBeingErnest

ответ

1

drawgreatcicle возвращает Matplotlib line2D, из которых можно получить данные с помощью get_data. Поэтому идея заключалась бы в том, чтобы нарисовать большой круг, получить данные и впоследствии удалить его. Используя данные, можно выполнить анимацию, итерацию по массиву.

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

fig = plt.figure(figsize=(6, 4)) 
m = Basemap(projection='merc', resolution=None, 
        llcrnrlon=-125, llcrnrlat=25, # LL = lower left 
        urcrnrlon=-60, urcrnrlat=55) #UR = upper right 
m.etopo(scale=0.5, alpha=0.5) 

# Ottawa to Anaheim 
# Ottawa 
lat1 = 45.4215 
lon1 = -75.6972 

# Anaheim 
lat2 = 33.8353 
lon2 = -117.9145 

line, = m.drawgreatcircle(lon1,lat1,lon2,lat2) 
x,y = line.get_data() 

line.remove() 
del line 

line, = plt.plot([],[]) 

def update(i): 
    line.set_data(x[:i], y[:i]) 

ani = matplotlib.animation.FuncAnimation(fig, update, frames=len(x), interval=100) 
ani.save(__file__+".gif", writer="imagemagick", fps=10) 
plt.tight_layout() 
plt.show() 

enter image description here

+0

Когда я скопировал этот код в Spyder, я получил эту ошибку: «Объект TypeError:« Path »не является итерируемым». Это произошло на линии, = m.drawgreatcircle (lon1, lat1, lon2, lat2). Если я удалю запятую на строке, я вернусь к объекту Path, который я вижу, это массив, но я не могу индексировать или получить доступ к значениям. –

+0

Ну, согласно [документации] (http://matplotlib.org/basemap/api/basemap_api.html#mpl_toolkits.basemap.Basemap.drawgreatcircle) 'drawgreatcircle' возвращает объект matplotlib.lines.Line2D. В приведенном выше решении используется этот факт, и он работает для меня на basemap версии 1.0.7, который был выпущен в 2013 году и который по-прежнему является последним официальным релизом, как я его вижу. Эта проблема была введена в 2014 году и [исправлена] (https://github.com/matplotlib/basemap/issues/322) в конце 2016 года, поэтому текущая версия разработки также должна вернуть строку2D. – ImportanceOfBeingErnest

+0

Если вы не хотите повышать или понижать установку базовой карты, должно быть возможно получить точки от пути. Если 'p' - это путь,' points = p.vertices' дает точки в 2D-массиве, такие, что 'x = points [:, 0]' и 'y = points [:, 1]' должны дать вам координаты. К сожалению, я не могу проверить это на данный момент. – ImportanceOfBeingErnest