zoukankan      html  css  js  c++  java
  • 飓风“桑迪”路径图的制作

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!

    飓风"桑迪" (Sandy)横扫美国东部,并在纽约附近登录,带走113条人命,并造成500亿美元的损失,桑迪也被列为美国历史上最昂贵的飓风。我们今天利用之前介绍过的Python的matplotlibbasemap包,来制作桑迪的路径图,重构桑迪的整个发育过程。

    下面是做成动画效果的GIF图 (由于博客园不允许上传2M以上的图片,所以分辨率有限,但你总可以作出一个高分辨率的动画。)

    我在图画中加入阴影,以显示夜晚时间。可以看到,桑迪形成之后,先在巴拿马附近徘徊,随后穿过古巴,并在此过程中加强为Hurricane-2。随后桑迪划过美国东海岸,之后突然转向西,直奔纽约,并于29日下午在纽约南侧登录。

     

    下载:数据文件

    数据文件中的wind(最大风速)单位为knot,pressure(气压)单位为mb,时间为世界时。


    绘制路径图的Python源码

    View Code
    # Written by Vamei
    
    from datetime import datetime, timedelta
    import re
    import numpy as np
    
    import matplotlib
    matplotlib.rcParams['text.color'] = 'white'
    matplotlib.rcParams['xtick.color'] = 'white'
    matplotlib.rcParams['ytick.color'] = 'white'
    
    from mpl_toolkits.basemap import Basemap
    import matplotlib.pyplot as plt
    
    font = 'monospace'
    
    # This function is to plot the base map
    def plotBase(fig, dt=None):
        m = Basemap(projection='merc',
                    lon_0=0,lat_0=0,lat_ts=0,
                    llcrnrlat=0,urcrnrlat=50,
                    llcrnrlon=-100,urcrnrlon=-50,
                    resolution='l')
        m.drawcountries(linewidth=1, color='k')
        m.drawmapscale(-90, 5, -90, 5, 1000, barstyle='fancy')
        m.bluemarble(scale=1)
    
        # Get Position of NYC, longitude -74.0064, latitude 40.7142
        x,y    = m(-74.0064, 40.7142)
        # Plot NYC
        m.scatter(x, y, s=100,  marker='*', color='0.5', alpha=1)
        plt.text(x,y,'NYC', fontsize='15')
    
        if dt is not None: m.nightshade(dt, alpha = 0.3)
        return m
    
    # Hurricane category colors
    color_dict = {'TROPICAL DEPRESSION':'#AEF100', 'TROPICAL STORM':'#FFD600', 'HURRICANE-1':'#FF6440', 'HURRICANE-2':'#8506A9'}
    
    # Read data file, unzip from track.zip to get track.dat
    fn  = 'track.dat'
    rec = {'lat':[],'lon':[],'wind':[],'press':[],'dt':[],'cat':[]}
    for i,line in enumerate(file(fn)):
        if i == 0: continue  # Jump over the first line
        # replace multiple whitespaces with a single whitespace
        line   = re.sub(r"\s+", ' ', line)
        pieces = line.split(" ")
        # retrieve information
        rec['lat'].append(float(pieces[0]))
        rec['lon'].append(float(pieces[1]))
        rec['wind'].append(float(pieces[3]))
        rec['press'].append(float(pieces[4]))
        rec['cat'].append((" ".join(pieces[5:])).strip())
        time   = pieces[2]
        time   = "2012/" + time
        rec['dt'].append(datetime.strptime(time,"%Y/%m/%d/%HZ"))
    
    # Plot the track and the else
    N = len(rec['lat'])
    for idx in range(N):
        dt     = rec['dt'][idx]
        # Adjust time zone according to NYC
        lt     = dt - timedelta(hours=5)
        lon    = rec['lon'][idx]
        lat    = rec['lat'][idx]
        wind   = rec['wind'][idx]
        press  = rec['press'][idx]
        cat    = rec['cat'][idx]
        fig    = plt.figure()
        m      = plotBase(fig, dt)
        # From lon,lat to pixels
        x,y    = m(lon, lat)
        # Plot track
        for i in range(idx):
            a0,b0 = m(rec['lon'][i], rec['lat'][i])
            a1,b1 = m(rec['lon'][i+1], rec['lat'][i+1])
            m.plot((a0,a1),(b0,b1), linewidth=2.5,
                      color=color_dict[rec['cat'][i+1]])
        # Plot Sandy's current position
        m.scatter(x, y, s=100, c=color_dict[cat], alpha=0.8)
        # Annotate current position
        plt.annotate(
            cat, 
            xy = (x, y), xytext = (-5, -30),
            textcoords = 'offset points', ha = 'right', va = 'bottom',
            bbox = dict(boxstyle = 'round,pad=0.5', fc=color_dict[cat], alpha = 0.8),
            arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'))
    
        tx, ty = m(-98, 40)
        plt.text(tx,ty, 
                lt.strftime("Hurricane Sandy\n\nNYC LT:\n%Y-%m-%d %H:00:00\nData Source: NOAA\nBy Vamei"), 
                family=font,ha='left')
        # add a small axes to show pressure
        a = fig.add_axes([0.6,0.2,.15,.1])
        a.set_ylim((950,1000))
        a.set_xlim((-10,70))
        a.set_yticks([900,1050])
        a.set_xticks([0,60])
        a.set_title("Center Pressure (mb)", fontsize=10)
        a.plot(rec['press'])
        a.axvline(x=idx, color='r')
        # add a small axes to show wind
        a = fig.add_axes([0.6,0.4,.15,.1])
        a.set_ylim((0,100))
        a.set_xlim((-10,70))
        a.set_yticks([0,100])
        a.set_xticks([0,60])
        a.set_title("Max Wind (knots)", fontsize=10)
        a.plot(rec['wind'])
        a.axvline(x=idx, color='r')
    
        fig.savefig(('%04d.png' % idx))
        plt.close()

    下面放一个桑迪的卫星图,显示一下桑迪的惊人尺寸(来自NASA的GOES卫星)


    桑迪带来的大小灾难:

  • 相关阅读:
    c语言中srand和rand函数 生成随机数总结
    枚举类型
    VS2008快捷键使用技巧
    PV实现同步
    PV操作(深入显出)
    数字在排序数组中出现的次数
    两个链表的第一个公共结点
    数组中的逆序对
    第一个只出现一次的字符位置
    丑数
  • 原文地址:https://www.cnblogs.com/vamei/p/2758006.html
Copyright © 2011-2022 走看看