多轨迹绘制

之前在简书有发布过Python气象数据处理与绘图(12):轨迹(台风路径,寒潮路径,水汽轨迹)绘制,提问的人比较多,这里我给出比较完整的方法和代码。实际上本质还是循环(应该还有更简便的办法,有思路的小伙伴可以留言反馈)。由于之前的文件过于复杂,这次我重新使用Hysplit模式追踪了一些路径,数据文件供大家测试使用。

数据文件结构如下:

数据结构

这里解释一下红色框住的部分,(Hysplit模式运行一次默认从10,500,1000米三个高度追踪三条轨迹)第一个框为三条轨迹的序号,第二个框为追踪事件,这里-1.0指的是后向模拟1小时,我文件提供的是后向5天的追踪,所以最后会到-120。第三个框就是三维位置了。我一共提供了5次模拟的数据,一共是5*3=15条轨迹,每个轨迹为121(120+1起点)个时间点。

读取文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
import pandas as pd
#建立空数组存放三维位置
x = np.zeros((5,3,121),"float")
y = np.zeros((5,3,121),"float")
z = np.zeros((5,3,121),"float")
#读取文件
for i in range(5):
f_tmp = pd.read_csv("./{}".format(i),sep='\s+',skiprows=11,header=None, names=['a','b','c','d','e','f','g','h','i','j','k','l','m'])
f_tmp = np.array(f_tmp).reshape((121,3, 13))
x[i,0,:] = f_tmp[:,0,10]
y[i,0,:] = f_tmp[:,0,9]
z[i,0,:] = f_tmp[:,0,11]
x[i,1,:] = f_tmp[:,1,10]
y[i,1,:] = f_tmp[:,1,9]
z[i,1,:] = f_tmp[:,1,11]
x[i,2,:] = f_tmp[:,2,10]
y[i,2,:] = f_tmp[:,2,9]
z[i,2,:] = f_tmp[:,2,11]

绘制图形(这里只画了5条序号为2的轨迹):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from matplotlib.collections import LineCollection
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import cartopy.mpl.ticker as cticker
#地图底图
fig = plt.figure(figsize=(12,7))
proj = ccrs.PlateCarree(central_longitude=95)
leftlon, rightlon, lowerlat, upperlat = (90,150,20,60)
img_extent = [leftlon, rightlon, lowerlat, upperlat]
f_ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.6],projection = proj)
f_ax1.set_extent(img_extent, crs=ccrs.PlateCarree())
f_ax1.add_feature(cfeature.COASTLINE.with_scale('50m'))
f_ax1.add_feature(cfeature.LAKES, alpha=0.5)
f_ax1.set_xticks(np.arange(leftlon,rightlon+20,20), crs=ccrs.PlateCarree())
f_ax1.set_yticks(np.arange(lowerlat,upperlat+20,20), crs=ccrs.PlateCarree())
lon_formatter = cticker.LongitudeFormatter()
lat_formatter = cticker.LatitudeFormatter()
f_ax1.xaxis.set_major_formatter(lon_formatter)
f_ax1.yaxis.set_major_formatter(lat_formatter)
#轨迹
for i in range(5):
lon = x[i,2,:]
lat = y[i,2,:]
points = np.array([lon, lat]).T.reshape(-1, 1, 2)#整合经纬度
segments = np.concatenate([points[:-1], points[1:]], axis=1)
norm = plt.Normalize(0, 2000)#按0-2000的高度对色标标准化
lc = LineCollection(segments, cmap='jet', norm=norm,transform=ccrs.PlateCarree())
lc.set_array(z[i,2,1:])#颜色色组指定为高度,两个点中间为一条线,所以颜色数组应为点数减1,所以是z[i,2,1:]
line = f_ax1.add_collection(lc)
#色标
position=fig.add_axes([0.32, 0.01, 0.35, 0.025])
fig.colorbar(line,cax=position,orientation='horizontal',format='%d')
plt.show()

输出图形如下:

traj