You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Geopandas和Matplotlib为地图添加带渐变色的贸易流箭头?

解决地图贸易流箭头展示的技术方案

一、在国家图层上添加双向箭头

Geopandas本身不直接支持箭头绘制,通常结合Matplotlib的patches模块实现。核心思路是先获取国家中心坐标,再在中心附近绘制双向箭头(可通过两个反向箭头或双向样式模拟)。

步骤1:加载地理与贸易数据

import geopandas as gpd
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch
from matplotlib.colors import Normalize
from matplotlib.cm import ScalarMappable

# 加载世界国家地理数据(使用Geopandas自带数据集)
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
# 模拟贸易数据:键为国家名,值为(贸易额, 贸易伙伴)
trade_data = {
    'China': (1500, 'US'),
    'US': (1500, 'China'),
    'Germany': (800, 'France'),
    'France': (800, 'Germany')
}

步骤2:基于国家中心绘制箭头

fig, ax = plt.subplots(figsize=(12, 8))
# 绘制基础国家图层
world.plot(ax=ax, color='lightgray', edgecolor='white')

# 箭头参数配置
arrow_length = 0.5  # 箭头长度(地理坐标单位)
arrow_size = 20     # 箭头头部大小

for country_name, (value, partner) in trade_data.items():
    country = world[world.name == country_name]
    if not country.empty:
        # 获取国家几何中心坐标
        centroid = country.geometry.centroid.iloc[0]
        x, y = centroid.x, centroid.y
        
        # 绘制双向箭头(用<->样式直接生成双向箭头)
        arrow = FancyArrowPatch((x - arrow_length, y), (x + arrow_length, y),
                                arrowstyle='<->', mutation_scale=arrow_size, linewidth=2)
        ax.add_patch(arrow)

提示:若需根据贸易伙伴位置调整箭头方向,可通过伙伴国家的中心坐标计算角度,用math.atan2获取方位后修改箭头的起点/终点坐标。

二、为箭头添加渐变色并生成数值图例

通过将贸易值映射到颜色映射表(colormap),实现箭头颜色随数值渐变,再生成对应图例。

步骤1:建立数值-颜色映射关系

# 提取所有贸易值,创建归一化器(将值映射到0-1区间)
trade_values = [v for v, _ in trade_data.values()]
norm = Normalize(vmin=min(trade_values), vmax=max(trade_values))
# 选择颜色映射(比如'viridis',可替换为'coolwarm'等)
cmap = plt.get_cmap('viridis')

步骤2:绘制带渐变色的箭头

修改箭头绘制逻辑,加入颜色映射:

fig, ax = plt.subplots(figsize=(12, 8))
world.plot(ax=ax, color='lightgray', edgecolor='white')

for country_name, (value, partner) in trade_data.items():
    country = world[world.name == country_name]
    if not country.empty:
        centroid = country.geometry.centroid.iloc[0]
        x, y = centroid.x, centroid.y
        
        # 根据贸易值获取对应颜色
        arrow_color = cmap(norm(value))
        arrow = FancyArrowPatch((x - arrow_length, y), (x + arrow_length, y),
                                arrowstyle='<->', mutation_scale=arrow_size, linewidth=2,
                                facecolor=arrow_color, edgecolor=arrow_color)
        ax.add_patch(arrow)

步骤3:生成数值对应图例

# 创建颜色映射辅助对象,用于生成颜色条
sm = ScalarMappable(norm=norm, cmap=cmap)
sm.set_array([])  # 无需绑定数据,仅需颜色映射规则

# 添加垂直颜色条图例
cbar = plt.colorbar(sm, ax=ax, orientation='vertical', pad=0.02)
cbar.set_label('Trade Value (USD billion)')

plt.title('Country-to-Country Trade Flow')
plt.show()

进阶:结合Cartopy实现精准投影

如果需要更专业的地理投影支持,可搭配Cartopy:

import cartopy.crs as ccrs

fig, ax = plt.subplots(figsize=(12, 8), subplot_kw={'projection': ccrs.PlateCarree()})
# 绘制带投影的国家图层
world.plot(ax=ax, transform=ccrs.PlateCarree(), color='lightgray', edgecolor='white')
ax.coastlines()

# 箭头绘制逻辑(需指定投影转换)
for country_name, (value, partner) in trade_data.items():
    country = world[world.name == country_name]
    if not country.empty:
        centroid = country.geometry.centroid.iloc[0]
        x, y = centroid.x, centroid.y
        
        arrow_color = cmap(norm(value))
        arrow = FancyArrowPatch((x - arrow_length, y), (x + arrow_length, y),
                                arrowstyle='<->', mutation_scale=arrow_size, linewidth=2,
                                facecolor=arrow_color, edgecolor=arrow_color,
                                transform=ccrs.PlateCarree())
        ax.add_patch(arrow)

# 添加颜色条
sm = ScalarMappable(norm=norm, cmap=cmap)
sm.set_array([])
cbar = plt.colorbar(sm, ax=ax, orientation='vertical', pad=0.02)
cbar.set_label('Trade Value (USD billion)')

plt.title('Country-to-Country Trade Flow')
plt.show()

内容的提问来源于stack exchange,提问作者hbstha123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 13:42:42