跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
Python大前端算法

Python 使用 Folium 实现高德地图热力图可视化

综述由AI生成使用 Python 的 Folium 和 NiceGUI 库结合高德地图 API 实现热力图可视化。通过模拟数据生成随机坐标点,利用插件绘制热力图层,并支持在 NiceGUI 界面中动态展示地图及数据表格。代码包含基础文件保存版与服务器端交互版,实现了自定义图标、颜色映射及平滑过渡效果。

协议工匠发布于 2026/3/16更新于 2026/4/2511 浏览
Python 使用 Folium 实现高德地图热力图可视化

一、生成网页

import pandas as pd
import folium
from folium import plugins
import random

# 模拟数据生成
def generate_mock_data():
    # 生成模拟景点数据
    locations = []
    base_lat = 23.122373
    base_lon = 113.268027
    # 生成 100 个随机景点数据
    for i in range(100):
        # 在基础坐标附近生成随机偏移
        lat = base_lat + random.uniform(-0.1, 0.1)
        lon = base_lon + random.uniform(-0.1, 0.1)
        locations.append({'lat': lat, 'lon': lon})
    return pd.DataFrame(locations)

# 使用模拟数据替代 CSV 读取
data = generate_mock_data()

# 创建地图,使用高德地图底图(正确配置 attribution)
heatmap1 = folium.Map(
    location=[23.122373, 113.268027],
    zoom_start=10,
    control_scale=True,
    tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
    attr='&copy; <a href="http://ditu.amap.com/">高德地图</a>'
)

# 添加中心标记
folium.Marker(
    [23.122373, 113.268027], 
    popup='<i>中心点</i>', 
    icon=folium.Icon(icon='cloud', color='green')
).add_to(heatmap1)

# 检查数据中是否存在 lat 和 lon 列
if 'lat' in data.columns and 'lon' in data.columns:
    # 创建热力图数据
    heat_data = [[row["lat"], row["lon"]] for index, row in data.iterrows()]
    # 添加热力图层
    heatmap_layer = plugins.HeatMap(heat_data)
    heatmap1.add_child(heatmap_layer)
else:
    print("错误:数据中缺少 lat 或 lon 列")
    print("数据列名:", data.columns.tolist())

# 保存地图
heatmap1.save("folium_map1.html")
print("地图已保存为 folium_map1.html")
print(f"使用了 {len(data)} 个模拟数据点")

热力图效果

热力图效果

热力图效果

热力图效果

二、生成服务器网页

import pandas as pd
import folium
from folium import plugins
import random
from nicegui import ui
import os
import webbrowser
from pathlib import Path

# 模拟数据生成
def generate_mock_data():
    # 生成模拟景点数据
    locations = []
    base_lat = 23.122373
    base_lon = 113.268027
    # 生成 100 个随机景点数据
    for i in range(100):
        # 在基础坐标附近生成随机偏移
        lat = base_lat + random.uniform(-0.1, 0.1)
        lon = base_lon + random.uniform(-0.1, 0.1)
        locations.append({'lat': lat, 'lon': lon})
    return pd.DataFrame(locations)

# 生成热力图 HTML
def generate_heatmap_html():
    data = generate_mock_data()
    # 创建地图,使用高德地图底图
    heatmap1 = folium.Map(
        location=[23.122373, 113.268027],
        zoom_start=10,
        control_scale=True,
        tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
        attr='&copy; <a href="http://ditu.amap.com/">高德地图</a>'
    )
    # 添加中心标记
    folium.Marker(
        [23.122373, 113.268027], 
        popup='<i>中心点</i>', 
        icon=folium.Icon(icon='cloud', color='green')
    ).add_to(heatmap1)
    # 检查数据中是否存在 lat 和 lon 列
    if 'lat' in data.columns and 'lon' in data.columns:
        # 创建热力图数据
        heat_data = [[row["lat"], row["lon"]] for index, row in data.iterrows()]
        # 添加热力图层
        heatmap_layer = plugins.HeatMap(heat_data)
        heatmap1.add_child(heatmap_layer)
    else:
        print("错误:数据中缺少 lat 或 lon 列")
        print("数据列名:", data.columns.tolist())
    # 保存地图到临时文件
    temp_file = 'temp_heatmap.html'
    heatmap1.save(temp_file)
    return temp_file

# 创建 NiceGUI 界面
@ui.page('/')
def main():
    ui.label('热力图可视化').classes('text-2xl font-bold')
    # 生成热力图按钮
    def show_heatmap():
        html_file = generate_heatmap_html()
        # 在新标签页中打开热力图
        webbrowser.open(f'file://{os.path.abspath(html_file)}')
        ui.notify(f'热力图已生成并打开:{html_file}')
    ui.button('生成并查看热力图', on_click=show_heatmap).classes('mt-4')
    # 显示数据信息
    data = generate_mock_data()
    ui.label(f'模拟数据点数量:{len(data)}').classes('mt-4')
    # 显示前几行数据
    ui.label('前 5 行数据预览:').classes('mt-4')
    # 使用正确的 ui.table 语法
    columns = [
        {'name':'index','label':'Index','field':'index'},
        {'name':'lat','label':'纬度','field':'lat'},
        {'name':'lon','label':'经度','field':'lon'}
    ]
    rows = [
        {'index': i,'lat': row['lat'],'lon': row['lon']} 
        for i,(idx, row) in enumerate(data.head().iterrows())
    ]
    ui.table(columns=columns, rows=rows).classes('w-full')
    # 启动应用

if __name__ in {"__main__","__mp_main__"}:
    ui.run(title='热力图可视化应用', port=8080, reload=True)

三、改进版

import pandas as pd
import folium
from folium import plugins
import random
from nicegui import ui
import os
import webbrowser
from pathlib import Path
import numpy as np
import base64
from io import BytesIO

# 模拟数据生成
def generate_mock_data():
    # 生成模拟景点数据
    locations = []
    base_lat = 23.122373
    base_lon = 113.268027
    # 生成 100 个随机景点数据
    for i in range(100):
        # 在基础坐标附近生成随机偏移
        lat = base_lat + random.uniform(-0.1, 0.1)
        lon = base_lon + random.uniform(-0.1, 0.1)
        # 生成随机数值用于条形图高度和颜色
        value = random.uniform(1, 100)
        locations.append({'lat': lat, 'lon': lon, 'value': value})
    return pd.DataFrame(locations)

# 生成热力图 HTML 并转换为 base64
def generate_heatmap_base64():
    data = generate_mock_data()
    # 创建地图,使用高德地图底图
    heatmap1 = folium.Map(
        location=[23.122373, 113.268027],
        zoom_start=10,
        control_scale=True,
        tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
        attr='&copy; <a href="http://ditu.amap.com/">高德地图</a>',
        # 设置地图背景为蓝紫色
        style='background-color: #4B0082;'
    )
    # 添加中心标记
    folium.Marker(
        [23.122373, 113.268027], 
        popup='<i>中心点</i>', 
        icon=folium.Icon(icon='cloud', color='green')
    ).add_to(heatmap1)
    # 为每个点添加七彩条形图(使用 SVG 图形)
    for idx, row in data.iterrows():
        # 创建 SVG 条形图元素
        svg_bar_html = create_svg_bar(row['value'])
        # 计算条形图尺寸(长度变为原来的六倍,宽度为原来的四分之一)
        bar_width = 9
        bar_height = max(int(row['value']/5)*6, 30)+4
        if bar_height < 34:
            bar_height = 34
        icon = folium.DivIcon(
            html=svg_bar_html, 
            icon_size=(bar_width, bar_height), 
            icon_anchor=(bar_width // 2, bar_height // 2)
        )
        # 在地图上添加标记
        folium.Marker(
            [row['lat'], row['lon']], 
            icon=icon, 
            popup=f"数值:{row['value']:.2f}"
        ).add_to(heatmap1)
    # 添加颜色条例图
    add_smooth_color_legend(heatmap1)
    # 将地图保存为 HTML 字符串
    map_html = heatmap1._repr_html_()
    return map_html

# 创建 SVG 条形图
def create_svg_bar(value):
    # 计算条形图尺寸(长度变为原来的六倍,宽度为原来的四分之一)
    width = 5
    height = max(int(value / 5)*6, 30)
    border_width = 2
    svg_width = width + 2 * border_width
    svg_height = height + 2 * border_width
    # 创建渐变定义
    gradient_id = f"grad_{int(value * 100)}"
    # 生成渐变色条
    gradient_html = f'''
    <svg xmlns="http://www.w3.org/2000/svg">
        <defs>
            <linearGradient x1="0%" y1="100%" x2="0%" y2="0%">
    '''
    # 添加渐变停止点
    num_steps = 20
    for i in range(num_steps + 1):
        stop_value = (i / num_steps) * value
        color = get_smooth_color_by_value(stop_value)
        offset = i / num_steps
        gradient_html += f'<stop offset="{offset * 100}%" stop-color="{color}" />\n'
    gradient_html += f'''
            </linearGradient>
        </defs>
        <rect x="{border_width}" y="{border_width}" fill="url(#{gradient_id})" stroke="yellow" stroke-width="{border_width}"/>
    </svg>
    '''
    return gradient_html

# 根据数值映射平滑颜色
def get_smooth_color_by_value(value):
    # 归一化数值到 0-1 范围
    normalized_value = min(max(value / 100.0, 0), 1)
    # 定义彩虹色谱的关键点
    hue = normalized_value * 300
    # 0-300 度的色相范围(避免红色重复)
    h = hue / 60.0
    c = 1.0
    x = c * (1 - abs(h % 2 - 1))
    if 0 <= h < 1:
        r, g, b = c, x, 0
    elif 1 <= h < 2:
        r, g, b = x, c, 0
    elif 2 <= h < 3:
        r, g, b = 0, c, x
    elif 3 <= h < 4:
        r, g, b = 0, x, c
    elif 4 <= h < 5:
        r, g, b = x, 0, c
    else:
        r, g, b = c, 0, x
    # 转换为 0-255 范围
    r = int(r * 255)
    g = int(g * 255)
    b = int(b * 255)
    # 转换为十六进制
    return f'#{r:02x}{g:02x}{b:02x}'

# 添加平滑颜色条例图
def add_smooth_color_legend(m):
    # 创建颜色条的 HTML
    legend_html = '''
    <div>
        <p><b>数值范围</b></p>
        <div>
    '''
    # 生成渐变色条
    for i in range(100, 0, -1):
        color = get_smooth_color_by_value(i)
        legend_html += f'<div token interpolation>{color}; border: 0.5px solid black;'></div>'
    legend_html += '''
        </div>
        <div>
            <span>0</span>
            <span>50</span>
            <span>100</span>
        </div>
    </div>
    '''
    m.get_root().html.add_child(folium.Element(legend_html))

# 创建 NiceGUI 界面
@ui.page('/')
def main():
    ui.label('拉长版平滑过渡七彩条形图').classes('text-2xl font-bold')
    # 显示地图
    def show_map():
        map_html = generate_heatmap_base64()
        # 使用 ui.html 显示地图,添加 sanitize=False 参数
        ui.html(map_html, sanitize=False).classes('w-full h-screen')
    # 显示地图按钮
    ui.button('显示地图', on_click=show_map).classes('mt-4')
    # 显示数据信息
    data = generate_mock_data()
    ui.label(f'模拟数据点数量:{len(data)}').classes('mt-4')
    # 显示前几行数据
    ui.label('前 5 行数据预览:').classes('mt-4')
    # 使用正确的 ui.table 语法
    columns = [
        {'name':'index','label':'Index','field':'index'},
        {'name':'lat','label':'纬度','field':'lat'},
        {'name':'lon','label':'经度','field':'lon'},
        {'name':'value','label':'数值','field':'value'}
    ]
    rows = [
        {'index': i,'lat': row['lat'],'lon': row['lon'],'value': row['value']} 
        for i,(idx, row) in enumerate(data.head().iterrows())
    ]
    ui.table(columns=columns, rows=rows).props('dense flat bordered').classes('w-full')
    # 启动应用

if __name__ in {"__main__","__mp_main__"}:
    ui.run(title='拉长版平滑过渡七彩条形图应用', port=8080, reload=False)

热力图效果

热力图效果

目录

  1. 一、生成网页
  2. 模拟数据生成
  3. 使用模拟数据替代 CSV 读取
  4. 创建地图,使用高德地图底图(正确配置 attribution)
  5. 添加中心标记
  6. 检查数据中是否存在 lat 和 lon 列
  7. 保存地图
  8. 二、生成服务器网页
  9. 模拟数据生成
  10. 生成热力图 HTML
  11. 创建 NiceGUI 界面
  12. 三、改进版
  13. 模拟数据生成
  14. 生成热力图 HTML 并转换为 base64
  15. 创建 SVG 条形图
  16. 根据数值映射平滑颜色
  17. 添加平滑颜色条例图
  18. 创建 NiceGUI 界面
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 原生js事件绑定和事件移除
  • Qwen-Image-2512 技术亮点与 ComfyUI 部署指南
  • PostgreSQL 常用操作指南
  • Ubuntu 22.04 安装 Claude Code 并在 VSCode 中使用
  • Windows + WSL + Ubuntu 安装 OpenClaw 并配置飞书与百炼模型
  • Java 集合框架详解:原理、用法与实战选型
  • 工业级存储芯片 CSNP32GCR01-AOW 在无人机飞控系统中的应用实践
  • VSCode 创建 Python 项目及 PyCharm 项目迁移指南
  • AI原生应用开发:Llama模型的10个高级用法
  • 浏览器端 AI 绘画:Deeplearn.js 风格迁移技术解析
  • 华为 OD 机试真题:网上商城优惠活动
  • AI 与鸿蒙融合:游戏形态的变革与未来趋势
  • Java TCP 网络编程:从可靠传输到 Socket 实战
  • Spring AI 会话记忆多存储与提示词工程实战
  • Python 字节码逆向实战:pycdc 工具深度解析与应用
  • Sudachi 开源模拟器跨平台使用指南
  • 人工智能:自然语言处理在教育领域的应用与实战
  • Java 项目实战:AI 辅助开发电商系统核心功能模块
  • 基于 Docker 部署 Appsmith 并配置内网穿透远程访问
  • AiOnly 平台调用 GPT-5 API 与 RAG 构建智能客服机器人

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online