2014-01-05 74 views
2

下面的代碼會生成一個動畫底圖,但不完全是我想要的那個:我想要前一幀的散點圖消失,但它在動畫的其餘部分保持不變。如何爲matplotlib中的底圖上的散點圖創建動畫?

我懷疑它與我不瞭解底圖真的有什麼關係。我知道把它稱爲經緯度/垂直投影到x/y,但是當我調用event_map.scatter()時,我並不完全知道發生了什麼。

import random 
import os 
import numpy as np 

import matplotlib.pyplot as plt 
from mpl_toolkits.basemap import Basemap 
from matplotlib import animation 
import pandas as pd 
from IPython.display import HTML 


# Enables animation display directly in IPython 
#(http://jakevdp.github.io/blog/2013/05/12/embedding-matplotlib-animations/) 
from tempfile import NamedTemporaryFile 

VIDEO_TAG = """<video controls> 
<source src="data:video/x-m4v;base64,{0}" type="video/mp4"> 
Your browser does not support the video tag. 
</video>""" 

def anim_to_html(anim): 
    if not hasattr(anim, '_encoded_video'): 
     with NamedTemporaryFile(suffix='.mp4') as f: 
      anim.save(f.name, fps=20, extra_args=['-vcodec', 'libx264']) 
      video = open(f.name, "rb").read() 
     anim._encoded_video = video.encode("base64") 

    return VIDEO_TAG.format(anim._encoded_video) 

def display_animation(anim): 
    plt.close(anim._fig) 
    return HTML(anim_to_html(anim)) 

animation.Animation._repr_html_ = anim_to_html 



FRAMES = 20 
POINTS_PER_FRAME = 30 
LAT_MIN = 40.5 
LAT_MAX = 40.95 
LON_MIN = -74.15 
LON_MAX = -73.85 
FIGSIZE = (10,10) 
MAP_BACKGROUND = '.95' 
MARKERSIZE = 20 

#Make Sample Data 
data_frames = {} 
for i in range(FRAMES): 
    lats = [random.uniform(LAT_MIN, LAT_MAX) for x in range(POINTS_PER_FRAME)] 
    lons = [random.uniform(LON_MIN, LON_MAX) for x in range(POINTS_PER_FRAME)] 
    data_frames[i] = pd.DataFrame({'lat':lats, 'lon':lons})  


class AnimatedMap(object): 
    """ An animated scatter plot over a basemap""" 
    def __init__(self, data_frames): 
     self.dfs = data_frames 
     self.fig = plt.figure(figsize=FIGSIZE) 
     self.event_map = Basemap(projection='merc', 
       resolution='i', area_thresh=1.0, # Medium resolution 
       lat_0 = (LAT_MIN + LAT_MAX)/2, lon_0=(LON_MIN + LON_MAX)/2, # Map center 
       llcrnrlon=LON_MIN, llcrnrlat=LAT_MIN, # Lower left corner 
       urcrnrlon=LON_MAX, urcrnrlat=LAT_MAX) # Upper right corner 
     self.ani = animation.FuncAnimation(self.fig, self.update, frames=FRAMES, interval=1000, 
              init_func=self.setup_plot, blit=True, 
              repeat=False) 

    def setup_plot(self): 
     self.event_map.drawcoastlines() 
     self.event_map.drawcounties() 
     self.event_map.fillcontinents(color=MAP_BACKGROUND) # Light gray 
     self.event_map.drawmapboundary() 
     self.scat = self.event_map.scatter(x = [], y=[], s=MARKERSIZE,marker='o', zorder=10) 
     return self.scat 

    def project_lat_lons(self, i): 
     df = data_frames[i] 
     x, y = self.event_map(df.lon.values, df.lat.values) 
     x_y = pd.DataFrame({'x': x, 'y': y}, index=df.index) 
     df = df.join(x_y) 
     return df 

    def update(self, i): 
     """Update the scatter plot.""" 
     df = self.project_lat_lons(i) 
     self.scat = self.event_map.scatter(x = df.x.values, y=df.y.values, marker='o', zorder=10) 
     return self.scat, 


s = AnimatedMap(data_frames) 
s.ani 
+0

明顯顛簸是崎嶇的,由於某種原因,我不能修復它=( – Dan

回答

3

看起來你只是在每次更新時添加一個新的散點圖。您應該做的是在每次更新時更改現有路徑集合中的數據。嘗試一下沿線

def update(self, i): 
    """Update the scatter plot.""" 
    df = self.project_lat_lons(i) 
    new_offsets = np.vstack([df.x.values, df.y.values]).T 
    self.scat.set_offsets(new_offsets) 
    return self.scat, 

請注意,我沒有測試過這一點。

+0

這樣做,謝謝傑克 – Dan