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

如何基于Pandas DataFrame创建印尼Scattermapbox分层地图?

解决印尼区域Scattermapbox着色问题:DataFrame生成图层或独立文件方案

首先帮你修正下代码里的小错误:你获取区域名称的循环里,变量用了region但内部写了state['properties']['name'],这会导致NameError,得改成region['properties']['name']。接下来分两种方案解决你的需求:

一、直接用Pandas DataFrame生成图层字典(推荐)

这个方案不需要生成独立文件,直接把GeoJSON数据和你的统计DataFrame合并,动态生成每个区域的图层配置,根据统计值着色。

步骤说明:

  1. 加载印尼GeoJSON数据,提取每个区域的feature和名称
  2. 准备你的统计数据(比如人口、GDP,假设是一个包含region_name和对应数值的DataFrame)
  3. 将GeoJSON的feature和统计数据按区域名称合并
  4. 遍历合并后的数据,生成每个区域的图层字典,用颜色映射对应统计值

修正后的完整代码:

import pandas as pd
import plotly
import plotly.graph_objs as go
from plotly.colors import sequential

# 1. 加载印尼GeoJSON数据
geojson_url = 'https://raw.githubusercontent.com/N1x0/indonesia-geojson/master/indonesia-edit.geojson'
id_geojson = pd.read_json(geojson_url)

# 提取区域名称和对应的feature
region_features = []
region_names = []
for feature in id_geojson['features']:
    region_names.append(feature['properties']['name'])
    region_features.append(feature)

# 2. 模拟你的统计数据(替换成你实际的DataFrame)
stats_df = pd.DataFrame({
    'region_name': region_names,
    'population': [12000000, 9500000, 8200000] + [5000000]*(len(region_names)-3)  # 示例数据
})

# 3. 合并feature和统计数据
regions_data = pd.DataFrame({
    'name': region_names,
    'feature': region_features
}).merge(stats_df, left_on='name', right_on='region_name')

# 4. 生成颜色映射(根据population值)
min_pop = regions_data['population'].min()
max_pop = regions_data['population'].max()
color_scale = sequential.Reds

def get_color(value):
    # 计算数值在颜色刻度中的位置
    idx = int((value - min_pop)/(max_pop - min_pop) * (len(color_scale)-1))
    return color_scale[idx]

# 5. 生成Scattermapbox的layers
map_layers = []
for _, row in regions_data.iterrows():
    layer = dict(
        sourcetype='geojson',
        source={'type': 'FeatureCollection', 'features': [row['feature']]},
        type='fill',
        color=get_color(row['population']),
        opacity=0.7,
        # 可选:添加hover信息
        hoverinfo='text',
        text=f"{row['name']}: {row['population']:,}"
    )
    map_layers.append(layer)

# 6. 构建地图布局和数据
mapbox_access_token = '你的Mapbox密钥'
data = [go.Scattermapbox(
    lat=[],
    lon=[],
    mode='markers',
    marker=dict(size=0)  # 隐藏默认标记,只显示区域填充
)]

layout = go.Layout(
    height=900,
    autosize=True,
    showlegend=False,
    hovermode='closest',
    mapbox=dict(
        layers=map_layers,
        accesstoken=mapbox_access_token,
        bearing=0,
        center=dict(lat=0.7893, lon=113.9213),
        pitch=0,
        zoom=4.5,
        style='light'
    )
)

fig = go.Figure(data=data, layout=layout)
plotly.offline.plot(fig, filename='Chloropleth_Province_Population.html')

二、生成各区域独立GeoJSON文件(备选方案)

如果还是需要生成独立文件,修正你之前的create_region_files函数:问题在于你直接把DataFrame的行转成JSON,但实际上每个区域的GeoJSON需要是完整的FeatureCollection格式,而且遍历方式不对。

修正后的函数代码:

import json
import os

def create_region_files():
    # 创建保存目录
    save_dir = 'C:\\Users\\nicho\\Desktop\\Waste Management\\Map_Maker\\ID_regions'
    os.makedirs(save_dir, exist_ok=True)
    
    # 遍历每个feature
    for feature in id_geojson['features']:
        region_name = feature['properties']['name']
        # 生成完整的GeoJSON格式
        region_geojson = {
            "type": "FeatureCollection",
            "features": [feature]
        }
        # 保存文件(注意处理特殊字符,避免文件名错误)
        filename = f"{region_name.replace('/', '_')}.json"
        file_path = os.path.join(save_dir, filename)
        with open(file_path, 'w', encoding='utf-8') as f:
            json.dump(region_geojson, f, ensure_ascii=False, indent=2)

# 调用函数生成文件
create_region_files()

这样生成的每个文件都是标准的GeoJSON,可以直接作为Scattermapbox的layer source使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:28:19