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

如何通过池化作业并行生成多幅Matplotlib地图?

高效批量生成区域地图解决方案

问题背景

现有Matplotlib+Cartopy绘图脚本,需为多组经纬度范围批量生成区域地图。当前并行多次运行脚本的方式会重复加载大体积shapefile,导致内存占用高、效率低下,需求是实现仅加载一次shapefile的池化并行绘图方案。

核心思路

利用Python的multiprocessing.Pool实现进程池并行:在主进程中提前加载shapefile等公共资源,通过全局变量传递给子进程,避免重复加载;子进程仅负责接收区域参数、绘制并保存单张地图,最大化复用公共资源。

具体实现步骤与代码示例

from matplotlib import pyplot as plt, gridspec
import cartopy.crs as crs
from cartopy.io.shapereader import Reader
from cartopy.feature import ShapelyFeature
import multiprocessing as mp

# ---------------------- 主进程预加载公共资源 ----------------------
# 仅执行一次,所有子进程共享该资源
states_path = '/some/path/usstates.shp'
reader = Reader(states_path)
states_geoms = list(reader.geometries())  # 提前读取几何数据到内存
crs_proj = crs.LambertConformal()
states_feature = ShapelyFeature(states_geoms, crs_proj, facecolor='none', edgecolor='black')

# 切换为非交互式后端,避免多进程下Matplotlib GUI冲突
plt.switch_backend('Agg')

# ---------------------- 单区域绘图函数 ----------------------
def plot_region(extent, save_path):
    # 创建独立的绘图实例,避免子进程间资源冲突
    fig = plt.figure(figsize=(14,9))
    gs = gridspec.GridSpec(ncols=1, nrows=2, width_ratios=[1], height_ratios=[0.15, 3.00])
    gs.update(wspace=0.00, hspace=0.00)

    # 绘制顶部文本轴
    ax1 = fig.add_subplot(gs[0, :])
    ax1.text(0.00, 0.50, "Some Fun Text", fontsize=15)
    ax1.text(1.00, 0.50, "Some Other Fun Text", fontsize=15, ha='right')
    ax1.axis('off')  # 关闭轴元素,消除多余边框

    # 绘制地图轴
    ax2 = fig.add_subplot(gs[1, :], projection=crs_proj)
    ax2.set_extent(extent, crs=crs_proj)
    ax2.add_feature(states_feature, linewidth=1.25)

    # 保存图像并释放资源
    plt.savefig(save_path, dpi=100, bbox_inches='tight')
    plt.close(fig)  # 必须关闭,防止内存泄漏

# ---------------------- 批量并行执行 ----------------------
if __name__ == '__main__':
    # 示例:多组区域范围与对应保存路径
    region_tasks = [
        ([lon1_min, lon1_max, lat1_min, lat1_max], './region1.png'),
        ([lon2_min, lon2_max, lat2_min, lat2_max], './region2.png'),
        # 添加更多区域任务...
    ]

    # 启动进程池,进程数建议设为CPU核心数
    with mp.Pool(processes=mp.cpu_count()) as pool:
        # 用starmap传递多参数任务
        pool.starmap(plot_region, region_tasks)

关键优化说明

  • 公共资源复用:shapefile的几何数据和ShapelyFeature在主进程仅加载一次,所有子进程直接复用,彻底避免重复IO和内存冗余。
  • 独立绘图上下文:每个子进程创建专属figure对象,完成后立即关闭,避免跨进程资源冲突和内存泄漏。
  • 非交互式后端:Agg后端禁用GUI渲染,解决多进程下Matplotlib的线程安全问题。
  • 进程池复用:multiprocessing.Pool复用子进程,减少进程创建与销毁的额外开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:15:40