问题:
已知穿航行的经纬度记录,怎么在地图上画出?
思路:
1先画出地图,使用cartopy。
2然后再将不连续的点绘制在地图中,这样的连线就是轨迹了。
( cartopy库的安装见我的其他文章简明cartopy安装教程)
代码分解:
1.加载库
import os
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter
2.加载经纬度数据
data = np.loadtxt('metz_hr_3.txt')
ship_lat = data[:,35]
ship_lon = data[:,36]
3.画世界地图
def main():
fig = plt.figure(figsize=(16, 9))
proj = ccrs.PlateCarree()
ax = fig.add_subplot(111, projection=ccrs.PlateCarree(central_longitude=160.0))
# 设置经纬度区域
map_extent = [-180, 180, -90, 90]
ax.set_extent(map_extent, crs=proj) # type: ignore
# 放置图片, 渲染好看的海洋以及地形
ax.stock_img()
# 添加经纬度坐标
lon_min, lon_max, lat_min, lat_max = 0, 1, 2, 3
ax.set_yticks(np.arange(map_extent[lat_min], map_extent[lat_max]+1, 15), crs=proj)
ax.set_xticks(np.arange(map_extent[lon_min], map_extent[lon_max]+1, 15), crs=proj)
lon_formatter = LongitudeFormatter(degree_symbol='', dateline_direction_label=True)
lat_formatter = LatitudeFormatter(degree_symbol='')
ax.yaxis.set_major_formatter(lat_formatter)
ax.xaxis.set_major_formatter(lon_formatter)
ax.coastlines(resolution='10m',)
ax.gridlines()
ax.set_title("航线轨迹图", fontsize="large")
4.在地图上循环加点
for i in range(ship_lon.shape[0]):
ax.plot(ship_lon[i],ship_lat[i], 'o', markersize=4, color='red',label='ship', transform=ccrs.Geodetic())
这里需要transform=ccrs.Geodetic()是为了将坐标转化为地图上的经纬度
6.保存查看图片
# 保存图片
PNG_NAME = f"platedemo.png"
print(PNG_NAME)
fig.savefig(PNG_NAME, dpi=200, bbox_inches='tight')
# plt.cla()
# plt.close(fig)
# plt.close("all")
plt.show()
完整代码:
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 21 15:57:29 2023
@author: mayubin
"""
plt.figure()
import os
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter
#if os.popen("uname").read().strip() == "Darwin":
# mpl.rcParams["font.sans-serif"] = ["Arial Unicode MS"] # MacOS
#else:
# mpl.rcParams["font.sans-serif"] = ["SimHei"] # CentOS, Windows
#mpl.rcParams["axes.unicode_minus"] = False
data = np.loadtxt('metz_hr_3.txt')
ship_lat = data[:,35]
ship_lon = data[:,36]
def main():
fig = plt.figure(figsize=(16, 9))
proj = ccrs.PlateCarree()
ax = fig.add_subplot(111, projection=ccrs.PlateCarree(central_longitude=160.0))
# 设置经纬度区域
map_extent = [-180, 180, -90, 90]
ax.set_extent(map_extent, crs=proj) # type: ignore
# 放置图片, 渲染好看的海洋以及地形
ax.stock_img()
# 隐藏海洋
# ax.add_feature(cfeature.OCEAN, facecolor="white", zorder=20) # type: ignore
# 添加经纬度坐标
lon_min, lon_max, lat_min, lat_max = 0, 1, 2, 3
ax.set_yticks(np.arange(map_extent[lat_min], map_extent[lat_max]+1, 15), crs=proj)
ax.set_xticks(np.arange(map_extent[lon_min], map_extent[lon_max]+1, 15), crs=proj)
lon_formatter = LongitudeFormatter(degree_symbol='', dateline_direction_label=True)
lat_formatter = LatitudeFormatter(degree_symbol='')
ax.yaxis.set_major_formatter(lat_formatter)
ax.xaxis.set_major_formatter(lon_formatter)
ax.coastlines(resolution='10m',)
ax.gridlines()
ax.set_title("航线轨迹图", fontsize="large")
for i in range(ship_lon.shape[0]):
ax.plot(ship_lon[i],ship_lat[i], 'o', markersize=4, color='red',label='ship', transform=ccrs.Geodetic())
# 保存图片
PNG_NAME = f"guiji.png"
fig.savefig(PNG_NAME, dpi=200, bbox_inches='tight')
main()
结果
图 ETLFLUXDATABASE船只航行观测轨迹图