geom_hex与ggmap经纬度错位及自定义热力变量实现问题咨询
嘿,作为地理绘图新手碰到这俩问题太正常了,我帮你一步步拆解解决!
解决加拿大六边形热力图的两个核心问题
一、先搞定坐标垂直偏移的问题
坐标偏移这事啊,90%都是投影系统不匹配搞的鬼——加拿大常用的地图投影可不是默认的WGS84经纬度(EPSG:4326),而是专门的加拿大国家坐标系(比如EPSG:3978,适合全国范围)或者UTM分带投影。你得把原始的经纬度数据转换成和底图一致的投影才行。
具体操作步骤(用Geopandas+Matplotlib为例)
- 先把你的数据转成地理数据格式,明确原始投影是WGS84:
import geopandas as gpd from shapely.geometry import Point # 假设你的数据存在df里,列名是lat(纬度)、lon(经度)、value(热度变量) geometry = [Point(xy) for xy in zip(df.lon, df.lat)] gdf = gpd.GeoDataFrame(df, geometry=geometry, crs="EPSG:4326") # 声明原始数据是WGS84经纬度
- 转换成加拿大适配的投影(这里用EPSG:3978,覆盖全国的通用投影):
gdf_proj = gdf.to_crs("EPSG:3978")
- 加载加拿大底图,也要确保底图投影和数据一致:
# 用geopandas自带的低分辨率全球数据提取加拿大边界 world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres')) canada = world[world.name == 'Canada'].to_crs("EPSG:3978")
这样再绘图,坐标就不会出现偏移了!
二、用指定变量展示热度(而非默认的点数密度)
Matplotlib的hexbin默认是统计每个六边形内的点数(密度),但我们可以通过参数自定义,用你的目标变量来计算热度值:
方法1:直接用Matplotlib的hexbin(简单快速,适合新手)
import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(12, 8)) # 先画加拿大底图 canada.plot(ax=ax, color='white', edgecolor='black') # 核心参数设置:用C指定你的热度变量,reduce_C_function指定聚合方式 h = ax.hexbin( gdf_proj.geometry.x, gdf_proj.geometry.y, C=gdf_proj['your_value_column'], # 替换成你自己的热度变量列名 reduce_C_function=sum, # 可选sum(求和)、np.mean(均值)、np.median(中位数)等 gridsize=50, # 控制六边形大小,数值越大六边形越密 cmap='YlOrRd', # 配色方案,可根据喜好替换 alpha=0.7 ) # 添加颜色条说明 plt.colorbar(h, label='总热度值') plt.title('加拿大六边形热力图(基于自定义变量)') plt.show()
这里的reduce_C_function是关键——它会把每个六边形内所有点的热度变量值,用你指定的函数聚合,最终作为这个六边形的热度值。
方法2:手动生成六边形网格(更灵活,适合复杂需求)
如果需要精准控制六边形的大小、范围,或者后续要做更多分析,可以手动生成六边形网格再关联数据:
from shapely.geometry import Polygon import numpy as np # 1. 获取加拿大的边界范围 xmin, ymin, xmax, ymax = canada.total_bounds # 2. 生成六边形网格(这里设置边长为50公里,可根据需求调整) hex_grid = gpd.GeoDataFrame(geometry=gpd.GeoSeries.from_xy( *np.meshgrid(np.arange(xmin, xmax, 50000*1.732), np.arange(ymin, ymax, 75000)), crs="EPSG:3978" ).apply(lambda x: Polygon(x.buffer(50000, cap_style=3))).stack().reset_index(drop=True)) # 3. 空间连接:把每个点的变量值关联到对应的六边形 hex_heat = gpd.sjoin(hex_grid, gdf_proj, how='left', predicate='contains') # 聚合变量值(这里用求和,可替换成其他聚合方式) hex_heat = hex_heat.groupby(hex_heat.index)['your_value_column'].sum().reset_index() hex_heat = hex_grid.merge(hex_heat, left_index=True, right_on='index') # 4. 绘图展示 fig, ax = plt.subplots(figsize=(12, 8)) canada.plot(ax=ax, color='white', edgecolor='black') hex_heat.plot(ax=ax, column='your_value_column', cmap='YlOrRd', alpha=0.7, edgecolor='gray', legend=True) plt.title('加拿大自定义六边形热力图') plt.show()
这个方法适合需要精细化调整六边形参数,或者要对网格做后续分析的场景。
额外小贴士
- 如果用Plotly等其他工具绘图,同样要保证数据投影和底图一致,Plotly里可以通过
projection参数设置适配的投影(比如projection='mercator'或专门的加拿大投影)。 - 调试坐标偏移时,可以先单独画几个已知位置的点,和底图对比,确认投影转换后的坐标是否正确。
内容的提问来源于stack exchange,提问作者turbonstre
相关产品推荐
相关产品推荐

