如何使用 geopandas 和 matplotlib 在地图中添加带有颜色渐变的箭头?

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

我想在地图上显示国家之间的贸易流动。 为此,我想添加 1 或 2 个往返国家/地区的箭头,如下所示。 箭头应该有颜色渐变,代表某些数值。

1.如何使用geopandas或其他软件包在地图中的国家/地区顶部添加箭头?

  1. 如何使用颜色图向这些箭头添加颜色渐变?我还需要颜色值的图例。

python matplotlib geospatial spatial
1个回答
1
投票

这是使用 cartopy 的基本实现(并且基于例如 Cartopy - 使用注释的多个箭头):

import numpy as np

from matplotlib import pyplot as plt
from matplotlib import colormaps
from matplotlib.colors import Normalize
from matplotlib.cm import ScalarMappable

import cartopy.io.shapereader as shpreader
import cartopy.crs as ccrs

# required countries
required = ["Egypt", "Sudan", "South Sudan"]

# get the country border file (10m resolution) and extract
shpfilename = shpreader.natural_earth(
    resolution="10m",
    category="cultural",
    name="admin_0_countries",
)
reader = shpreader.Reader(shpfilename)
countries = reader.records()

# extract the specific country information
c = {
    co.attributes["ADMIN"]: co
    for co in countries if co.attributes["ADMIN"] in required
}

# get overall boundary box from country bounds
extents = np.array([c[cn].bounds for cn in c])
lon = [extents.min(0)[0], extents.max(0)[2]]
lat = [extents.min(0)[1], extents.max(0)[3]]

# get country centroids
centroids = {
    cn: [c[cn].geometry.centroid.x, c[cn].geometry.centroid.y] for cn in c
}

# plot the countries
ax = plt.axes(projection=ccrs.PlateCarree())

for cn in c.values():
    ax.add_geometries(cn.geometry, crs=ccrs.PlateCarree(), edgecolor="white", facecolor="lightgray")

ax.set_extent([lon[0] - 1, lon[1] + 1, lat[0] - 1, lat[1] + 1])

# flows in and out of country pairs
transfers = {"Egypt,Sudan": [2.3, 8.9], "Sudan,South Sudan": [6.5, 0.9]}

# set up a colormap
cmap = colormaps.get_cmap("Greens")
tmax = np.array([v for v in transfers.values()]).max()
tmin = np.array([v for v in transfers.values()]).min()
norm = Normalize(tmin, tmax)

offset = 1.0

for tr in transfers:
    c1, c2 = tr.split(",")
    cent1 = centroids[c1]
    cent2 = centroids[c2]

    # one way
    t1 = transfers[tr][0]
    col = cmap(norm(t1))

    ax.annotate(
        "",
        xy=(cent2[0] - offset, cent2[1] - offset),
        xytext=(cent1[0] - offset, cent1[1] - offset),
        xycoords="data",
        arrowprops={"facecolor": col},
    )

    # other way
    t2 = transfers[tr][1]
    col = cmap(norm(t2))

    ax.annotate(
        "",
        xy=(cent1[0] + offset, cent1[1] + offset),
        xytext=(cent2[0] + offset, cent2[1] + offset),
        xycoords="data",
        arrowprops={"facecolor": col},
    )

# set the colorbar
sm = ScalarMappable(norm, cmap)

fig = plt.gcf()
fig.colorbar(sm, ax=ax)

plt.show()

产生:

您可能想尝试一下箭头起点和终点的实际位置。

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