Python轻松实现某德地图可视化功能

 更新时间:2026年01月05日 09:06:33   作者:大数据自动化RPA  
文章介绍了如何使用Python轻松实现某德地图的可视化,并提供了两种解决方案:一种是生成本地网页,另一种是生成服务器网页的改进版,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

Python轻松实现某德地图可视化,直接给出解决方案

一.、生成网页

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/" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >高德地图</a>'
)
# 添加中心标记
folium.Marker(
    [23.122373, 113.268027],
    popup='<i>J哥</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)} 个模拟数据点")
from pathlib import Path
# 路径配置
BASE_DIR = Path(__file__).parent  # 脚本所在目录
DB_DIR = BASE_DIR / '图样'
DB_DIR.mkdir(exist_ok=True)
HTML_FILE_PATH = DB_DIR / "002.html"  # 明确HTML文件完整路径
# 保存地图
heatmap1.save(DB_DIR /"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/" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >高德地图</a>'
    )
    # 添加中心标记
    folium.Marker(
        [23.122373, 113.268027],
        popup='<i>J哥</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/" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >高德地图</a>',
        # 设置地图背景为蓝紫色
        style='background-color: #4B0082;'
    )
    # 添加中心标记
    folium.Marker(
        [23.122373, 113.268027],
        popup='<i>J哥</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  # 5 + 2*2 (原始宽度 + 两边边框)
        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  # 20 / 4
    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 width="{svg_width}" height="{svg_height}" xmlns="http://www.w3.org/2000/svg">
        <defs>
            <linearGradient id="{gradient_id}" 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}" width="{width}" height="{height}" 
              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度的色相范围(避免红色重复)
    # 将HSV转换为RGB
    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 style="
        position: fixed; 
        bottom: 50px; 
        right: 50px; 
        z-index:9999; 
        background-color: white; 
        padding: 10px;
        border:2px solid grey;
        border-radius: 5px;
        font-size: 14px;
        box-shadow: 0 0 10px rgba(0,0,0,0.2);
        ">
        <p style="text-align: center; margin: 0 0 10px 0;"><b>数值范围</b></p>
        <div style="display: flex; flex-direction: column; height: 900px; width: 7.5px; margin: 0 auto;">
    '''
    # 生成渐变色条(长度变为原来的六倍)
    for i in range(100, 0, -1):  # 从100到1
        color = get_smooth_color_by_value(i)
        legend_html += f'<div style="height: 9px; background-color: {color}; border: 0.5px solid black;"></div>'  # 1.5px * 6
    legend_html += '''
        </div>
        <div style="display: flex; justify-content: space-between; margin-top: 10px;">
            <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)

到此这篇关于Python轻松实现某德地图可视化功能的文章就介绍到这了,更多相关python地图可视化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • django1.8使用表单上传文件的实现方法

    django1.8使用表单上传文件的实现方法

    Django是一个开放源代码的Web应用框架,由Python写成。这篇文章主要介绍了django1.8使用表单上传文件的相关资料,非常不错具有参考借鉴价值,感兴趣的朋友一起看看吧
    2016-11-11
  • 在Django中预防CSRF攻击的操作

    在Django中预防CSRF攻击的操作

    这篇文章主要介绍了在Django中预防CSRF攻击的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • 详解pandas的外部数据导入与常用方法

    详解pandas的外部数据导入与常用方法

    这篇文章主要介绍了详解pandas的外部数据导入与常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • python使用正则表达式来获取文件名的前缀方法

    python使用正则表达式来获取文件名的前缀方法

    今天小编就为大家分享一篇python使用正则表达式来获取文件名的前缀方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • python使用socket向客户端发送数据的方法

    python使用socket向客户端发送数据的方法

    这篇文章主要介绍了python使用socket向客户端发送数据的方法,涉及Python使用socket实现数据通信的技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • 利用Python制作一个愚人节整蛊消息框

    利用Python制作一个愚人节整蛊消息框

    又到了一年一度的愚人节了,本文小编为大家准备了用Python语言制作的愚人节整蛊消息框,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-04-04
  • python初学之用户登录的实现过程(实例讲解)

    python初学之用户登录的实现过程(实例讲解)

    下面小编就为大家分享一篇python初学之用户登录的实现过程(实例讲解),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • python pip安装包出现:Failed building wheel for xxx错误的解决

    python pip安装包出现:Failed building wheel for xxx错误的解决

    今天小编就为大家分享一篇python pip安装包出现:Failed building wheel for xxx错误的解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • Pyqt5中6种按钮的具体使用

    Pyqt5中6种按钮的具体使用

    本文主要介绍了Pyqt5中6种按钮的具体使用,包括QPushButton、QRadioButton、QCheckBox、QToolButton等,具有一定的参考价值,感兴趣的可以了解一下
    2025-09-09
  • Python多线程经典问题之乘客做公交车算法实例

    Python多线程经典问题之乘客做公交车算法实例

    这篇文章主要介绍了Python多线程经典问题之乘客做公交车算法,简单描述了乘客坐公交车问题并结合实例形式分析了Python多线程实现乘客坐公交车算法的相关技巧,需要的朋友可以参考下
    2017-03-03

最新评论