从GMT格式文本文件读取经纬度坐标并转换为Numpy数组用于Basemap绘图
解决GMT线段文本转Basemap兼容的NumPy数组问题
问题概述
你有GMT格式的线段数据,格式示例如下:
122 55 122 56 122.5 57 > 123 25.25 123 25.27
其中>是不同线段的分隔符,需要将这些坐标转换成二维NumPy数组,以便用Basemap结合plt.plot或plt.scatter进行绘图。
完整实现方案
1. 解析GMT文本并转换为NumPy数组
核心思路是先按分隔符拆分线段,再将每个线段的坐标对整理成二维数组。下面是可直接复用的代码:
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap # 替换成你的GMT文本内容,也可以从文件读取(比如用open().read()) gmt_data = "122 55 122 56 122.5 57 > 123 25.25 123 25.27" # 1. 分割不同线段,清理空白内容 segments = [seg.strip() for seg in gmt_data.split(">") if seg.strip()] # 2. 将每个线段转换为(n, 2)形状的NumPy数组 line_coords = [] for seg in segments: # 拆分坐标字符串为数值,再重塑为二维数组(每行对应一个经纬度点) coords = np.array(list(map(float, seg.split()))).reshape(-1, 2) line_coords.append(coords) # 打印验证结果 for idx, arr in enumerate(line_coords): print(f"第{idx+1}条线段的坐标数组:") print(arr)
2. 结合Basemap绘制线段
拿到转换后的数组后,就可以直接对接Basemap的绘图函数了:
# 初始化Basemap实例(这里以东亚区域为例,可根据需求调整投影和范围) m = Basemap(llcrnrlon=70, llcrnrlat=15, urcrnrlon=140, urcrnrlat=55, projection='lcc', lat_1=30, lat_2=60, lon_0=105) # 绘制基础地图元素 m.drawcoastlines(linewidth=0.8) m.drawcountries(linewidth=0.5) m.drawparallels(np.arange(15, 56, 10), labels=[1,0,0,0]) m.drawmeridians(np.arange(70, 141, 10), labels=[0,0,0,1]) # 遍历每个线段数组,转换投影并绘图 for coords in line_coords: # 将原始经纬度转换为Basemap的投影坐标 x, y = m(coords[:, 0], coords[:, 1]) # 绘制线段,可自定义样式 plt.plot(x, y, marker='^', linestyle='-', color='#ff4444', linewidth=2) plt.title("GMT线段转换后Basemap绘图示例") plt.show()
关键细节说明
- 清理空白:分割后用
strip()和空字符串过滤,避免因文本首尾或连续分隔符产生无效数据 - 自动重塑:
reshape(-1, 2)会自动根据坐标数量调整行数,无需手动计算点数,适配任意长度的线段 - 投影转换:Basemap要求先将经纬度转成它的投影坐标,再传入
plt.plot,否则会出现坐标偏移
内容的提问来源于stack exchange,提问作者Pakox.Wang




