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

如何为Folium地图GeoJson多边形添加Plotly图表弹窗?

问题描述

我有一个包含多要素的GeoJSON文件,已在Folium交互式地图上展示多边形。每个城市对应的Plotly图表存储在当前工作目录的graphs/CityName.HTML路径下。目前可实现多边形的悬停或点击弹窗,但无法将Plotly图表以HTML字符串形式添加到GeoJSON弹窗中。曾尝试给Marker添加弹窗但未成功,希望通过循环遍历GeoJSON要素,为每个多边形添加对应图表的弹窗。现有代码片段如下:

import folium
import geopandas as gpd
import codecs

map = folium.Map(location=['51.096246199999996', '4.178629103169916'], tiles="cartodbpositron", zoom_start=9)
geojson_file_df = gpd.read_file('Refgem_geojson.json')

loc = 'Project GEO ICT'
title_html = '''
             <h3 align="center" style="font-size:20px"><b>{}</b></h3>
             '''.format(loc)
map.get_root().html.add_child(folium.Element(title_html))


g_map = folium.GeoJson(
    geojson_file,
    name="GeoJson",
    style_function=lambda x: {'fillColor': 'orange'}
).add_to(map)


folium.GeoJsonTooltip(
    fields=['NISCODE','NAAM', 'OPPERVL'],
    aliases=['NISCODE', 'Naam', 'Oppervlakte'],
    sticky=False
).add_to(g_map)


folium.GeoJsonPopup(
    fields=["NAAM", "Average Prices: " ,"Woonhuis", "Villa", "Studio"],
    aliases=["Naam", "Average Prices: ","Woonhuis", "Villa", "Studio"]
).add_to(g_map)

html="""
    <iframe src="""" + codecs.open("graphs/AARTSELAAR.html", 'r').read() + """" width="850" height="400"  frameborder="0">    
    """
popup1 = folium.Popup(folium.Html(html, script=True))

folium.Marker(['51.096246199999996','4.178629103169916'],popup=popup1,icon=folium.Icon( icon='home', prefix='fa')).add_to(map)

map
解决方案

核心是利用folium.GeoJson的popup参数绑定自定义函数,动态读取对应城市的Plotly图表HTML文件,生成专属弹窗。替代原有的GeoJsonPopup(仅支持绑定GeoJSON属性字段),实现图表嵌入。

修改后的完整代码

import folium
import geopandas as gpd
import codecs
from folium import Html, Popup

# 初始化地图,避免变量名与内置函数冲突
m = folium.Map(location=['51.096246199999996', '4.178629103169916'], tiles="cartodbpositron", zoom_start=9)

# 添加地图标题
loc = 'Project GEO ICT'
title_html = '''
             <h3 align="center" style="font-size:20px"><b>{}</b></h3>
             '''.format(loc)
m.get_root().html.add_child(folium.Element(title_html))

# 读取GeoJSON数据
geojson_data = gpd.read_file('Refgem_geojson.json')

# 定义弹窗生成函数:根据GeoJSON要素属性加载对应城市的图表
def generate_city_popup(feature):
    city_name = feature['properties']['NAAM']
    graph_file_path = f"graphs/{city_name}.html"
    
    try:
        # 读取Plotly图表的HTML内容
        with codecs.open(graph_file_path, 'r', encoding='utf-8') as file:
            graph_html_content = file.read()
        
        # 构建包含城市名和图表的弹窗HTML
        popup_html = Html(f"""
        <h4 style="margin:0 0 10px 0;">{city_name}</h4>
        <div style="width:800px; height:400px; overflow:auto;">{graph_html_content}</div>
        """, script=True)
        
        # 返回带内容的弹窗,设置最大宽度
        return Popup(popup_html, max_width=850)
    
    except FileNotFoundError:
        # 若图表文件不存在,返回提示弹窗
        return Popup(Html(f"<h4>{city_name}</h4><p>暂无可用图表数据</p>", script=True))

# 添加GeoJSON图层,绑定自定义弹窗生成函数
folium.GeoJson(
    geojson_data,
    name="GeoJson",
    style_function=lambda x: {'fillColor': 'orange'},
    popup=generate_city_popup  # 关键:绑定动态弹窗函数
).add_to(m)

# 保留原有悬停提示框
folium.GeoJsonTooltip(
    fields=['NISCODE','NAAM', 'OPPERVL'],
    aliases=['NISCODE', 'Naam', 'Oppervlakte'],
    sticky=False
).add_to(m)

# 保存地图到本地(可选)
m.save('city_map_with_graphs.html')

# 显示地图
m

关键说明

  1. 变量名修正:将原map变量改为m,避免与Python内置函数冲突。
  2. 动态弹窗函数:generate_city_popup从GeoJSON要素中提取城市名,拼接图表文件路径,读取HTML内容后直接嵌入弹窗(替代原iframe方式,避免路径/跨域问题)。
  3. 异常处理:针对图表文件缺失的情况,返回友好提示弹窗,保证程序稳定运行。
  4. 移除冗余组件:删除原GeoJsonPopup和测试用Marker,避免弹窗冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:01:13