根据经纬度数据画出船只航行路径图(cartopy + matplotlib)

问题:

已知穿航行的经纬度记录,怎么在地图上画出?

思路:

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船只航行观测轨迹图

以下是一个可能的代码优化方案: 1. 删除未使用的库和模块 在代码中,导入了一些未使用的库和模块,包括numpy、get_cmap、from_levels_and_colors等,可以将其删除以减少代码量。 2. 删除重复导入的库和模块 在代码中,导入了多个相同的库和模块,包括cartopycartopy.crs、cartopy.feature,可以将其合并为一个导入语句。 3. 优化变量的命名和赋值 在代码中,一些变量的命名不够直观,例如co、co1等,可以改为更具有描述性的名称。另外,一些变量的赋值方式可以简化为一行。 4. 简化形绘制代码 在代码中,形绘制的代码比较冗长,可以简化为一行或者几行,同时可以将一些公共的参数提取出来作为全局变量,以便后续的绘。 综上所述,以下是一个可能的优化后的代码: ``` import netCDF4 as nc import cartopy.crs as ccrs import cartopy.feature as cfeature from netCDF4 import Dataset from wrf import to_np, getvar, get_cartopy warnings.filterwarnings('ignore') file = 'D:/transfer/wrfout_d01_2016-03-01_00_00_00' ncfile = Dataset(file) latitude = ncfile.variables['XLAT'][0][:] longitude = ncfile.variables['XLONG'][0][:] co = ncfile.variables['co'][1][1][:][:] cart_proj = get_cartopy(getvar(ncfile, "co")) plt.contourf(longitude, latitude, co, levels=38, cmap='hot', projection=cart_proj) plt.colorbar() ax = plt.axes(projection=cart_proj) ax.set_extent([90, 110, 0, 30]) ax.add_feature(cfeature.COASTLINE) ax.add_feature(cfeature.BORDERS) plt.show() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值