如何使用Matplotlib绘制不同投影下的天梭指标体?

gev0vcfq  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(88)

这是我关于堆栈溢出的第一个问题,我希望有人能帮助我:)
我想在matplotlib中用PlateCaree和Mercator-projection投影地球表面,并在上面添加小圆圈以获得天梭指示线。
我在网上找了很多,但是我找不到正确的答案。到目前为止,我可以画出我的圆圈,但它们保持不变,不像它们应该做的那样伸展。以下是我到目前为止所做的:

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))

字符串
非常感谢:)

bvhaajcl

bvhaajcl1#

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度。



edit:以下是Cartopy使用的自动和手动方法的示例:

from shapely.geometry import Polygon
from cartopy.geodesic import Geodesic
import matplotlib.pyplot as plt
import matplotlib as mpl
import cartopy.crs as ccrs
import cartopy
from pyproj import geod

fig, ax = plt.subplots(figsize=(4,4), facecolor="w", dpi=100, layout="compressed", subplot_kw=dict(projection=ccrs.PlateCarree()))

radius = 300 # km
n_samples = 80
lons = (0, 0, 0, 0)
lats = (20, 40, 60, 80)

# auto
ax.tissot(rad_km=radius, lons=lons, lats=lats, n_samples=n_samples, fc='none', ec="C3", lw=2)

# manual
for lon, lat in zip(lons,lats):
    circle = Geodesic().circle(lon, lat, radius*1000., n_samples=n_samples)
    feature = cartopy.feature.ShapelyFeature([Polygon(circle)], ccrs.Geodetic(), fc='none', ec="C0", lw=2, linestyle="--")
    ax.add_feature(feature)

ax.coastlines(alpha=.5, lw=0.4)
ax.set_extent((-45,45,0,90), crs=ccrs.PlateCarree())


相关问题