如何使用Matplotlib绘制不同投影下的Tissot指标线?

问题描述 投票:0回答:1

这是我关于堆栈溢出的第一个问题,我希望有人可以帮助我:)

我想使用 PlateCaree 和 Mercator 投影在 matplotlib 中投影地球表面,并向其添加小圆圈以获得天梭指示线。

我查了很多资料,但在网上找不到正确的答案。到目前为止,我可以画出我的圆圈,但它们保持不变,并且没有像预期的那样拉伸。这是我到目前为止所拥有的:

import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import math

def main():
    # Setting values
    proj = ccrs.PlateCarree()
    lonW = -90
    lonE = 90
    latS = -90
    latN = 90
    cLat = (latN + latS) / 2
    cLon = (lonW + lonE) / 2
    res = '110m'

    fig = plt.figure(figsize=(11, 8.5))
    ax = plt.subplot(1, 1, 1, projection=proj)
    ax.gridlines( draw_labels=True, linewidth=2, color='gray', alpha=0.5, linestyle='--')
    ax.set_extent([lonW, lonE, latS, latN], crs=proj)
    ax.coastlines(resolution=res, color='black')

    ax.add_feature(cfeature.LAND)
    ax.add_feature(cfeature.OCEAN)
    ax.add_feature(cfeature.BORDERS, linestyle='-', linewidth=0.5)
    ax.add_feature(cfeature.LAKES)

    # Adding a single coordinate
    ax.scatter(24.3, 61.83, color='red', marker='o', s=6, transform=proj, label='Hyytiälä')

    # Adding first circle
    center_lon, center_lat = 0, 0
    r = 10
    ax.add_patch(mpatches.Circle(xy=[center_lon, center_lat], radius=r, color='red', alpha=0.3, transform=proj, zorder=30))

    # Adding a second circle
    center_lon, center_lat = 0, 30
    r = 10
    ax.add_patch(mpatches.Circle(xy=[center_lon, center_lat], radius=r, color='red', alpha=0.3, transform=proj, zorder=30))

    # Adding a third circle
    center_lon, center_lat = 0, 60
    r = 10
    ax.add_patch(mpatches.Circle(xy=[center_lon, center_lat], radius=r, color='red', alpha=0.3, transform=proj, zorder=30))

    # Adding a last circle
    center_lon, center_lat = 0, 90
    r = 10
    ax.add_patch(mpatches.Circle(xy=[center_lon, center_lat], radius=r, color='red', alpha=0.3, transform=proj, zorder=30))

非常感谢:)

python matplotlib cartopy
1个回答
0
投票

Cartopy 已经将此内置方法作为任何轴上的专用方法,因此更简单的方法是:

import matplotlib.pyplot as plt
import matplotlib as mpl
import cartopy.crs as ccrs

config = {
    "Plate Carree": dict(projection=ccrs.PlateCarree()),
    "Mercator": dict(projection=ccrs.Mercator()),
}

layout = [[name] for name in config.keys()]

fig, axs = plt.subplot_mosaic(
    layout, figsize=(6,9), facecolor="w", dpi=100, 
    layout="compressed", per_subplot_kw=config, height_ratios=[1.2,2],
)

for name, ax in axs.items():
    
    ax.coastlines()
    ax.set_title(name)
    ax.tissot(alpha=.3, fc="C3")

我不确定这是否是您想要的,您可以通过如下所示的圆圈手动完成。为此,您可以用它替换

ax.tissot()
,或多或少地使用您已经定义的点:

from shapely.geometry import Polygon
from cartopy.geodesic import Geodesic
    # in the axes loop:
    for lon, lat, r in [
        (0,0,10*110000),
        (0,30,10*110000),
        (0,60,10*110000),
        (0,89,10*110000), # 90° has a height of 0
    ]:

        circle_points = Geodesic().circle(lon=lon, lat=lat, radius=r)
        ax.add_geometries(
            (Polygon(circle_points),), facecolor='C3', alpha=.5,
            crs=ccrs.PlateCarree(),
        )

半径应以米为单位,我粗略地定义为每度 110000 米,使用 10 度的半径。

© www.soinside.com 2019 - 2024. All rights reserved.