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

Matplotlib contourf填充等高线图转GeoJSON并Folium展示异常

解决Matplotlib填充等高线转GeoJSON并在Folium中正确显示的问题

在Google Colab环境中使用plt.contourf生成填充等高线图后,将其转换为GeoJSON导入Folium时出现多边形构建错误,以下是问题分析和修正方案:

问题根源

  1. 层级与Collections不匹配:np.linspace生成11个等高线值,对应10个填充区间,但contourf_plot.collections的数量是10个,直接zip会导致层级对应错误。
  2. 路径处理不当:Matplotlib的Path可能包含带内环的复杂多边形,直接取vertices无法区分内外环,导致GeoJSON多边形结构错误。
  3. 冗余的坐标闭合操作:path.to_polygons()已自动闭合多边形,手动重复起点会导致GeoJSON格式异常。

修正后的代码

import numpy as np
import folium
import matplotlib.pyplot as plt
from matplotlib.colors import to_hex, Normalize
import requests
from io import BytesIO
import xarray as xr

# 下载并读取NetCDF数据
url = "https://www.star.nesdis.noaa.gov/socd/mecb/sar/AKDEMO_products/APL_winds/tropical/2024/SH052024_BELAL/STAR_SAR_20240116013937_SH052024_05S_MERGED_FIX_3km.nc"
response = requests.get(url)
dataset = xr.open_dataset(BytesIO(response.content))

sar_wind = dataset['sar_wind'].values
latitude = dataset['latitude'].values
longitude = dataset['longitude'].values

# 生成等高线层级(11个值对应10个填充区间)
iso_values_filled = np.linspace(np.min(sar_wind), np.max(sar_wind), 11)
contourf_plot = plt.contourf(longitude, latitude, sar_wind, levels=iso_values_filled, cmap='viridis')

# 转换为GeoJSON FeatureCollection
geojson_data_polygon = {"type": "FeatureCollection", "features": []}
norm = Normalize(vmin=iso_values_filled.min(), vmax=iso_values_filled.max())

# 遍历每个填充区间(对应collection),使用区间的中间值映射颜色
for idx, collection in enumerate(contourf_plot.collections):
    # 取当前区间的上下限,计算中间值作为颜色映射基准
    level_min = iso_values_filled[idx]
    level_max = iso_values_filled[idx+1]
    level_mid = (level_min + level_max) / 2
    color_hex = to_hex(plt.cm.viridis(norm(level_mid)))
    
    for path in collection.get_paths():
        # 将路径分解为多边形(自动处理内外环)
        polygons = path.to_polygons()
        if not polygons:
            continue
        
        # GeoJSON Polygon格式:外环+多个内环
        coordinates = [polygon.tolist() for polygon in polygons]
        geojson_data_polygon["features"].append({
            "type": "Feature",
            "geometry": {
                "type": "Polygon",
                "coordinates": coordinates
            },
            "properties": {
                "level_min": level_min,
                "level_max": level_max,
                "color": color_hex
            }
        })

# 创建Folium地图并添加GeoJSON图层
center_lat, center_lon = np.mean(latitude), np.mean(longitude)
mymap_polygon = folium.Map(location=[center_lat, center_lon], zoom_start=8)

folium.GeoJson(
    geojson_data_polygon,
    style_function=lambda feature: {
        'fillColor': feature['properties']['color'],
        'color': 'none',  # 隐藏边界线,避免重叠混乱
        'fillOpacity': 0.7
    }
).add_to(mymap_polygon)

# 显示地图
mymap_polygon

关键修正说明

  • 层级匹配:通过enumerate遍历collections,对应每个填充区间的上下限,用中间值映射颜色,确保层级与颜色对应准确。
  • 路径分解:使用path.to_polygons()将复杂路径拆分为外环和内环,符合GeoJSON Polygon的结构要求(外环在前,内环在后)。
  • 优化样式:将边界线设为'none',避免多个层级的边界线重叠导致视觉混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:13:18