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

如何使用folium制作分类choropleth地图为不同类别配置独特色

Folium按分类字段绘制唯一色Choropleth地图实现方案

原生folium.Choropleth接口默认支持数值型字段的梯度着色,你需要按Category分类给每个国家分配唯一区分色的需求,通过自定义样式映射即可实现,不需要额外依赖复杂插件。
核心逻辑:提前建立「分类-唯一色」的映射关系,遍历地理边界要素时,通过ISO_A3编码匹配对应分类的填充色,未匹配到数据的国家默认填充浅灰色
额外优化:补充自定义分类图例,弥补原生接口不支持分类图例的问题

完整可运行代码

import pandas as pd
import folium
import json
from branca.element import MacroElement, Template

# 1. 加载/构造你的数据集,提前处理文本转义问题
df = pd.DataFrame([
    ["DEU", "Belletristik", 25.9],
    ["AUT", "Ratgeber", 25.6],
    ["CHE", "Belletristik", 27.7],
    ["USA", "Fiction & related items", 11.0],
    ["PRT", "Mathematics & science", 84.0],
    ["GBR", "Children's, Teenage & educational", 18.9]
], columns=["ISO_A3", "Category", "Percent"])
# 替换数据里的HTML转义字符,避免显示异常
df["Category"] = df["Category"].str.replace("&", "&")

# 2. 为每个唯一分类分配高区分度的固定颜色
unique_categories = df["Category"].drop_duplicates().tolist()
# 可自行替换为你需要的色值,数量和分类数保持一致即可
category_colors = ["#e6194B", "#3cb44b", "#ffe119", "#4363d8", "#f58231", "#911eb4"][:len(unique_categories)]
cat_to_color = dict(zip(unique_categories, category_colors))
# 提前生成ISO_A3到对应填充色的映射表,渲染时直接查询提升效率
iso_to_color = df.set_index("ISO_A3")["Category"].map(cat_to_color).to_dict()

# 3. 初始化folium底图,可自行调整中心点和缩放级别
m = folium.Map(location=[30, 10], zoom_start=3, tiles="OpenStreetMap")

# 4. 加载地理边界数据:替换为你本地带ISO_A3编码字段的GeoJSON文件路径
with open("world_iso3.geojson", "r", encoding="utf-8") as f:
    geo_boundary = json.load(f)

# 5. 自定义要素样式规则
def feature_style(feature):
    # 注意:如果你的GeoJSON里ISO_A3直接存在feature根节点下,把下一行改成 feature.get("ISO_A3", "")
    iso_code = feature["properties"].get("ISO_A3", "")
    fill_color = iso_to_color.get(iso_code, "#f5f5f5")
    return {
        "fillColor": fill_color,
        "color": "#333333",
        "weight": 0.7,
        "fillOpacity": 0.75
    }

# 6. 添加着色后的地理图层,可自定义tooltip显示内容
folium.GeoJson(
    geo_boundary,
    style_function=feature_style,
    tooltip=folium.GeoJsonTooltip(
        fields=["ISO_A3", "name"],
        aliases=["国家编码:", "国家名称:"],
        localize=True
    )
).add_to(m)

# 7. 添加自定义分类图例
legend_template = '''
{% macro html(this, kwargs) %}
<div style="position:fixed; left:20px; bottom:20px; z-index:9999; background:#fff; padding:10px 14px; border-radius:6px; box-shadow:0 0 5px rgba(0,0,0,0.25);">
    <p style="margin:0 0 8px 0; font-weight:bold;">图书分类</p>
    {% for cat, color in this.color_map.items() %}
    <div style="display:flex; align-items:center; margin:4px 0;">
        <div style="width:16px; height:16px; background:{{color}}; border:1px solid #444; margin-right:8px;"></div>
        <span style="font-size:13px;">{{cat}}</span>
    </div>
    {% endfor %}
</div>
{% endmacro %}
'''
legend = MacroElement()
legend._template = Template(legend_template)
legend.color_map = cat_to_color
m.get_root().add_child(legend)

# 渲染保存为本地HTML文件,在Jupyter环境中可直接输出m查看
m.save("category_map.html")

调整说明

  • 如果你的GeoJSON文件里国家编码字段不是ISO_A3,只需要修改feature_style函数里取编码的字段名,保证和DataFrame里的ISO_A3能匹配上即可
  • 分类颜色可以根据需求替换,只要保证每个分类对应唯一色值即可,建议选择区分度高的定性色板,避免相近颜色无法区分
  • 如果需要在悬浮提示里展示Percent数值,只需要先把Percent字段合并到GeoJSON的properties里,再把字段加到GeoJsonTooltip的fields列表中即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 10:24:22