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

如何用Seaborn绘制带真实RSSI值色条的静态地图插值热力图?

实现带真实RSSI值色条的插值RSSI热力图

问题背景

我尝试用Python和Seaborn在静态地图上绘制RSSI(接收信号强度指示)点值的插值热力图,数据导出为CSV,还有对应的shape文件。当前代码用weights=gdf['rssi']生成的热力图视觉效果符合预期,但色条显示的是KDE权重计算结果,不是真实的RSSI值(范围-55至-145);换成hue=gdf['rssi']后色条数值正确,但无法生成插值热力图。需要实现带真实RSSI值色条的插值热力图。

原代码:

import requests as r
import io
import matplotlib.pyplot as plt
import pandas as pd
import geopandas as gpd
import seaborn as sns
import tilemapbase as tm

df=pd.read_csv('rangemap.csv')
gdf = gpd.GeoDataFrame(df, 
    geometry = gpd.points_from_xy(df['lon'], df['lat']), 
    crs = 'EPSG:4326')
gdf = gdf.to_crs("EPSG:3857")

vlk = gpd.read_file("Valkeakoski.shp")
vlk = vlk.to_crs("EPSG:3857")

tm.init(create=True)
extent = tm.extent_from_frame(vlk)
fig, ax = plt.subplots(figsize=(12,10),layout="constrained")
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
plotter = tm.Plotter(extent, tm.tiles.build_OSM(), width=1000)
plotter.plot(ax)
sns.kdeplot(data=gdf,x=gdf['geometry'].x,y=gdf['geometry'].y,fill=True,cmap='turbo',alpha=0.3,levels=20,weights=gdf['rssi'],cbar=True,ax=ax,zorder=3)
vlk.plot(color=(1,1,1,0),edgecolor="black",linewidth=0.5,ax=ax)

解决方案

Seaborn的kdeplot本质是核密度估计,用weights参数只会改变密度分布的权重,不会直接插值出真实的RSSI值。要实现真实RSSI值的插值热力图,需要用空间插值方法(如线性插值、最近邻或径向基函数),将离散的RSSI点值插值到连续网格上,再绘制热力图。

修改后的代码

import matplotlib.pyplot as plt
import pandas as pd
import geopandas as gpd
import tilemapbase as tm
import numpy as np
from scipy.interpolate import griddata

# 读取并处理数据
df = pd.read_csv('rangemap.csv')
gdf = gpd.GeoDataFrame(df, 
    geometry=gpd.points_from_xy(df['lon'], df['lat']), 
    crs='EPSG:4326')
gdf = gdf.to_crs("EPSG:3857")

vlk = gpd.read_file("Valkeakoski.shp")
vlk = vlk.to_crs("EPSG:3857")

# 初始化地图
tm.init(create=True)
extent = tm.extent_from_frame(vlk)
fig, ax = plt.subplots(figsize=(12,10), layout="constrained")
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
plotter = tm.Plotter(extent, tm.tiles.build_OSM(), width=1000)
plotter.plot(ax)

# 提取坐标和RSSI值
x = gdf['geometry'].x.values
y = gdf['geometry'].y.values
rssi = gdf['rssi'].values

# 创建覆盖地图范围的网格
xi = np.linspace(x.min(), x.max(), 500)
yi = np.linspace(y.min(), y.max(), 500)
xi, yi = np.meshgrid(xi, yi)

# 执行插值(可选方法:'linear'/'nearest'/'cubic')
zi = griddata((x, y), rssi, (xi, yi), method='linear')

# 绘制插值热力图
contour = ax.contourf(xi, yi, zi, levels=20, cmap='turbo', alpha=0.3, zorder=3)
# 添加色条,设置范围为真实RSSI区间
cbar = plt.colorbar(contour, ax=ax)
cbar.set_label('RSSI (dBm)')
cbar.set_ticks(np.arange(-145, -54, 10))  # 匹配原始RSSI范围

# 叠加边界
vlk.plot(color=(1,1,1,0), edgecolor="black", linewidth=0.5, ax=ax)

plt.show()

关键说明

  1. 空间插值:使用scipy.interpolate.griddata将离散点的RSSI值插值到规则网格上,三种常用插值方法可选:
    • nearest:最近邻插值,速度快但边缘不光滑
    • linear:线性插值,平衡光滑度与计算量
    • cubic:三次插值,最光滑但计算量大,可能出现异常值
  2. 色条校准:通过cbar.set_ticks手动设置色条刻度,完全匹配原始RSSI的区间(-145至-55),确保色条显示真实数值
  3. 图层顺序:用zorder参数保证热力图在地图上方、边界图层在最上层,避免遮挡

这样生成的热力图既能呈现插值后的信号分布,色条也会准确显示真实的RSSI值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:32:03