您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Python中如何使用Cartopy库代码绘制台风路径
## 引言
台风路径可视化是气象分析和灾害预警中的重要技术手段。Python作为数据科学领域的主流语言,结合专业地理信息可视化库Cartopy,能够高效绘制具有地理坐标参考的台风路径图。本文将详细介绍利用Cartopy绘制台风路径的完整技术方案,包含数据获取、坐标转换、地图投影选择以及高级可视化技巧。
## 一、环境准备与库安装
### 1.1 必要库及其作用
```python
# 核心库清单
import cartopy.crs as ccrs # 地理坐标系统支持
import cartopy.feature as cfeature # 地理特征数据
import matplotlib.pyplot as plt # 绘图基础框架
import pandas as pd # 数据清洗处理
import numpy as np # 数值计算
安装命令(建议使用conda环境):
conda install -c conda-forge cartopy matplotlib
Cartopy自动调用Natural Earth地理数据集,首次使用时会下载: - 海岸线数据(coastline) - 国界数据(borders) - 河流数据(rivers) - 行政区划数据(states)
推荐数据源: - 中国气象局热带气旋数据集(CMA-STI) - 日本气象厅最佳路径数据(JMA) - IBTrACS国际综合台风数据库
示例数据结构(CSV格式):
time,lat,lon,pressure,windspeed,category
2023-08-01 12:00,15.2,128.7,985,35,TS
2023-08-02 00:00,16.8,127.3,980,40,STS
def clean_typhoon_data(df):
"""数据清洗函数"""
# 坐标范围验证
df = df[(df['lon'] >= 100) & (df['lon'] <= 180) &
(df['lat'] >= 0) & (df['lat'] <= 50)]
# 时间格式标准化
df['time'] = pd.to_datetime(df['time'], format='%Y%m%d%H')
# 风速单位统一(节→m/s)
if 'windspeed' in df.columns:
df['windspeed'] = df['windspeed'] * 0.5144
return df.drop_duplicates('time')
常用投影对比:
投影类型 | 适用场景 | 代码示例 |
---|---|---|
PlateCarree | 全球等距矩形 | ccrs.PlateCarree() |
LambertConformal | 中纬度地区 | ccrs.LambertConformal() |
Mercator | 赤道附近区域 | ccrs.Mercator() |
Orthographic | 半球展示 | ccrs.Orthographic() |
东亚地区推荐配置:
proj = ccrs.LambertConformal(
central_longitude=125,
central_latitude=30,
standard_parallels=(15, 45)
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(1, 1, 1, projection=proj)
# 设置地图范围(东亚及西太平洋)
ax.set_extent([100, 160, 0, 50], crs=ccrs.PlateCarree())
# 添加地理特征
ax.add_feature(cfeature.LAND.with_scale('50m'))
ax.add_feature(cfeature.OCEAN.with_scale('50m'))
ax.add_feature(cfeature.COASTLINE.with_scale('50m'))
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linestyle=':')
ax.add_feature(cfeature.STATES.with_scale('50m'), linestyle=':')
# 添加网格线
gl = ax.gridlines(
draw_labels=True,
linewidth=1, color='gray', alpha=0.5,
linestyle='--')
gl.top_labels = False
gl.right_labels = False
def plot_typhoon_track(ax, track_df):
"""绘制台风路径核心函数"""
# 转换坐标到地图投影
x = track_df['lon'].values
y = track_df['lat'].values
points = ax.projection.transform_points(
ccrs.PlateCarree(), x, y)
# 绘制路径线
ax.plot(
points[:, 0], points[:, 1],
color='red', linewidth=2,
marker='o', markersize=4,
transform=ax.projection,
label='Track')
# 标记起点终点
ax.text(
points[0, 0], points[0, 1], 'S',
transform=ax.projection,
fontsize=10, weight='bold')
ax.text(
points[-1, 0], points[-1, 1], 'E',
transform=ax.projection,
fontsize=10, weight='bold')
def add_intensity(ax, track_df):
"""添加强度信息"""
cmap = plt.get_cmap('RdYlBu_r')
norm = plt.Normalize(
vmin=track_df['windspeed'].min(),
vmax=track_df['windspeed'].max())
sc = ax.scatter(
track_df['lon'], track_df['lat'],
c=track_df['windspeed'], cmap=cmap, norm=norm,
transform=ccrs.PlateCarree(),
s=50, edgecolor='k', zorder=5)
# 添加色标
plt.colorbar(
sc, ax=ax, orientation='horizontal',
label='Wind Speed (m/s)', pad=0.05)
def add_time_markers(ax, track_df, interval=6):
"""每隔N小时添加时间标记"""
for idx, row in track_df.iloc[::interval].iterrows():
ax.text(
row['lon']+1, row['lat']-1,
row['time'].strftime('%m%d%H'),
transform=ccrs.PlateCarree(),
fontsize=8, bbox=dict(facecolor='white', alpha=0.7))
def plot_wind_radius(ax, track_df):
"""绘制7级/10级风圈"""
for _, row in track_df.iloc[::6].iterrows():
# 7级风圈
circle = plt.Circle(
(row['lon'], row['lat']),
row['radius7']/111, # 转换为经纬度度数
transform=ccrs.PlateCarree(),
fill=False, color='blue', alpha=0.3)
ax.add_patch(circle)
# 10级风圈(若存在)
if 'radius10' in row:
circle = plt.Circle(
(row['lon'], row['lat']),
row['radius10']/111,
transform=ccrs.PlateCarree(),
fill=False, color='red', alpha=0.3)
ax.add_patch(circle)
# 数据加载
df = pd.read_csv('mangkhut_2018.csv')
df = clean_typhoon_data(df)
# 创建地图
proj = ccrs.LambertConformal(
central_longitude=125, central_latitude=20)
fig = plt.figure(figsize=(15, 10))
ax = fig.add_subplot(1, 1, 1, projection=proj)
# 设置地图范围
ax.set_extent([100, 150, 5, 35], crs=ccrs.PlateCarree())
# 添加底图要素
ax.stock_img()
ax.add_feature(cfeature.COASTLINE.with_scale('50m'))
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linestyle=':')
# 绘制路径
plot_typhoon_track(ax, df)
add_intensity(ax, df)
add_time_markers(ax, df, interval=12)
# 添加标题和图例
plt.title('Super Typhoon Mangkhut (2018) Track', fontsize=16)
plt.legend(loc='upper right')
# 保存输出
plt.savefig('mangkhut_track.png', dpi=300, bbox_inches='tight')
plt.close()
def plot_multiple_tracks(track_list):
"""多台风路径对比"""
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(1, 1, 1,
projection=ccrs.PlateCarree())
# 设置公共底图
ax.set_extent([110, 160, 5, 45])
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.COASTLINE)
# 为每个台风分配颜色
colors = plt.cm.tab10(np.linspace(0, 1, len(track_list)))
for df, color in zip(track_list, colors):
ax.plot(
df['lon'], df['lat'],
color=color, linewidth=2,
transform=ccrs.PlateCarree(),
label=df['name'].iloc[0])
plt.legend()
plt.title('Typhoon Tracks Comparison (2016-2020)')
症状:路径显示位置偏移
解决方案:
# 显式坐标转换
from cartopy.mpl.geoaxes import GeoAxes
GeoAxes._transform_xy = lambda self, x, y, transform: (
self.projection.transform_points(transform, x, y)[:, :2].T
with_scale('50m')
降低数据精度ax.add_feature(cfeature.LAND.with_scale('50m'),
facecolor=(0.9,0.9,0.9), zorder=0)
格式 | 适用场景 | DPI设置 |
---|---|---|
PNG | 网页/文档嵌入 | 300+ |
印刷/矢量编辑 | - | |
SVG | 进一步矢量处理 | - |
通过Cartopy库绘制台风路径不仅能够实现专业级的地理可视化效果,还能结合Python强大的数据处理能力进行深度分析。本文介绍的技术方案可扩展应用于其他气象要素可视化,如降水分布、温度场等。建议读者在实践中尝试不同的地图投影和样式配置,开发出更具表现力的气象可视化作品。 “`
注:本文代码示例已在Cartopy 0.21+和Matplotlib 3.5+环境下测试通过。实际应用时请根据具体数据格式调整参数。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。