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

如何使用Folium实现鼠标悬停高亮国家边界?

在Folium中实现鼠标悬停高亮国家边界的方案

你目前用Plotly实现了可运行的人口 choropleth 地图,想切换到Folium实现鼠标悬停高亮单个国家边界的功能对吧?Folium本身没有直接封装好的一键函数,但通过GeoJson图层配合自定义样式函数,完全可以实现这个交互效果,下面是具体的实现步骤和代码示例:

核心思路

Folium的GeoJson图层支持两个关键函数来控制交互样式:

  • style_function:定义地图元素的默认显示样式(包括choropleth的颜色映射)
  • highlight_function:定义鼠标悬停时的高亮样式(比如加粗边界、改变填充透明度)

另外可以配合GeoJsonTooltip实现悬停时显示国家名称、人口等自定义信息。

完整代码示例(结合你的数据处理逻辑)

首先保留你原有的数据处理部分,然后替换Plotly的可视化代码为以下Folium代码:

# 保留你原有的数据处理代码(从import到df生成的部分)
import urllib.request
import json
import numpy as np
import pandas as pd
import csv
import itertools
import folium
from folium.features import GeoJsonTooltip, GeoJsonPopup

# --- 你的原有数据处理代码 ---
with urllib.request.urlopen("http://api.population.io:80/1.0/countries") as url:
    api_data = json.loads(url.read().decode())
twoD_data = np.array(list(api_data.values()))
all_countries = twoD_data.ravel()

country_and_countryCodes_csv = pd.read_csv("http://kejser.org/wp-content/uploads/2014/06/Country.csv", delimiter='|')
country_and_countryCodes = country_and_countryCodes_csv[["CountryName","Alpha3Code"]]
chained_country_list = set(itertools.chain.from_iterable(country_and_countryCodes.values.tolist())) & set(all_countries)

country_ready_for_fetch = []
for country in chained_country_list:
    try:
        if '/' not in country:
            j = country.replace(" ","%20")
            country_ready_for_fetch.append(j)
    except AttributeError:
        pass

year = "/2013"
date = year + '-01-01'
country_population = []
for country in country_ready_for_fetch:
    url = "http://api.population.io:80/1.0/population/"
    with urllib.request.urlopen(url + country + date) as url:
        data = json.loads(url.read().decode())
        country_population.append(country)
        country_population.append(data)

result = {}
for i in range(0, len(country_population), 2):
    result[country_population[i]] = country_population[i+1]['total_population']['population']
result = {key.replace('%20', ' '): value for key, value in result.items()}

l = np.array(country_and_countryCodes).tolist()
for i in l:
    i.append(result.get(i[0]))
df = pd.DataFrame(l)
df.columns = ['Country','CountryCode','Population']
df['CountryCode'] = df['CountryCode'].str.upper()

# --- 以下是Folium可视化部分 ---
# 1. 初始化地图
m = folium.Map(location=[20, 0], zoom_start=2)

# 2. 加载国家边界GeoJSON(确保ISO3代码匹配你的数据)
geojson_url = "https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json"
with urllib.request.urlopen(geojson_url) as url:
    country_geojson = json.loads(url.read().decode())

# 3. 定义颜色映射函数(实现choropleth效果)
def get_color(population):
    if population is None:
        return '#cccccc'
    elif population < 10000000:
        return '#fee5d9'
    elif population < 50000000:
        return '#fcae91'
    elif population < 200000000:
        return '#fb6a4a'
    else:
        return '#cb181d'

# 4. 定义默认样式函数
def style_function(feature):
    # 匹配当前国家的人口数据
    country_code = feature['id']
    pop = df.loc[df['CountryCode'] == country_code, 'Population'].values
    pop = pop[0] if len(pop) > 0 else None
    return {
        'fillColor': get_color(pop),
        'color': '#333333',
        'weight': 1,
        'fillOpacity': 0.7
    }

# 5. 定义悬停高亮样式函数
def highlight_function(feature):
    return {
        'weight': 3,
        'color': '#000000',
        'fillOpacity': 0.9
    }

# 6. 添加GeoJson图层到地图
folium.GeoJson(
    country_geojson,
    style_function=style_function,
    highlight_function=highlight_function,
    tooltip=GeoJsonTooltip(
        fields=['name'],
        aliases=['国家名称:'],
        localize=True
    ),
    popup=GeoJsonPopup(
        fields=['name'],
        aliases=['国家:'],
        localize=True,
        max_width=300,
        labels=True
    )
).add_to(m)

# 7. 保存或显示地图(Jupyter Notebook中直接运行m即可显示)
m.save('population_map.html')
# 在Jupyter中显示地图
# m

关键部分说明

  1. GeoJSON数据匹配:示例中用的GeoJSON以ISO3代码作为id,正好和你的df['CountryCode']匹配,这样才能正确关联人口数据。如果你的GeoJSON用的是其他标识(比如国家名称),需要调整匹配逻辑。
  2. 样式函数:style_function负责根据人口值设置填充色,实现choropleth效果;highlight_function在鼠标悬停时加粗边界、提高填充透明度,达到高亮效果。
  3. 交互信息:GeoJsonTooltip实现悬停时的轻量信息展示,GeoJsonPopup则是点击时的弹窗信息,你可以根据需要添加Population字段到tooltip或popup中。

额外提示

  • 如果需要更精细的颜色映射,可以用branca.colormap模块来生成连续的颜色渐变,比如:
    from branca.colormap import LinearColormap
    colormap = LinearColormap(colors=['#fee5d9', '#fcae91', '#fb6a4a', '#cb181d'], vmin=df['Population'].min(), vmax=df['Population'].max())
    
    然后在style_function中调用colormap(pop)获取颜色。
  • 确保你的GeoJSON数据完整,部分小型国家可能在基础GeoJSON中没有包含,需要调整数据源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:05:28