如何用Plotly将hexbin网格裁剪至指定JSON边界(非洲大陆)
实现Plotly Hexbin Mapbox裁剪至非洲边界内
可以通过结合GeoPandas的空间判断功能,过滤掉非洲边界外的六边形网格单元,具体实现步骤如下:
核心思路
- 提取
create_hexbin_mapbox生成的六边形网格中心坐标 - 用GeoPandas判断每个六边形中心是否处于非洲边界范围内
- 过滤掉边界外的网格数据,重新构建绘图用的Trace
修改后的完整代码
import numpy as np import pandas as pd import plotly.graph_objs as go import plotly.figure_factory as ff import geopandas as gpd import json # 示例数据 data = pd.DataFrame({ 'LAT': [1,5,6,7,5,6,7,5,6,7,5,6,7,12,-40,50], 'LON': [10,10,11,12,10,11,12,10,11,12,10,11,12,-20,40,50], }) # 获取并合并非洲边界为单一多边形 gdf_poly = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres")) Afr_gdf_area = gdf_poly[gdf_poly['continent'] == 'Africa'].dissolve(by='continent') # 生成初始六边形热力图 fig = ff.create_hexbin_mapbox( data_frame=data, lat="LAT", lon="LON", nx_hexagon=25, opacity=0.4, labels={"color": "Point Count"}, mapbox_style='carto-positron', zoom=1 ) # 提取初始hexbin的核心数据 hex_trace = fig.data[0] hex_lats = hex_trace.lat hex_lons = hex_trace.lon hex_counts = hex_trace.z # 将六边形中心转为GeoDataFrame,用于空间判断 hex_gdf = gpd.GeoDataFrame( {'count': hex_counts}, geometry=gpd.points_from_xy(hex_lons, hex_lats), crs="EPSG:4326" ) # 标记位于非洲境内的六边形 hex_gdf['in_africa'] = hex_gdf.geometry.within(Afr_gdf_area.geometry.iloc[0]) # 过滤出非洲境内的网格数据 filtered_lats = hex_lats[hex_gdf['in_africa']] filtered_lons = hex_lons[hex_gdf['in_africa']] filtered_counts = hex_counts[hex_gdf['in_africa']] # 更新图中的Trace为过滤后的数据 fig.data[0] = go.Histogram2dContour( lat=filtered_lats, lon=filtered_lons, z=filtered_counts, colorscale=hex_trace.colorscale, opacity=hex_trace.opacity, colorbar=hex_trace.colorbar, name=hex_trace.name, showscale=True ) # 添加非洲边界填充层(可选) fig.update_layout(mapbox={ "layers": [ { "source": json.loads(Afr_gdf_area.geometry.to_json()), "below": "traces", "type": "fill", "color": "orange", "opacity": 0.1, "line": {"width": 1} }, ], }) fig.show()
关键细节说明
- 合并边界多边形:使用
dissolve方法将分散的非洲国家多边形合并为一个整体,避免多次空间判断的冗余 - 空间过滤逻辑:通过
within方法精准判断六边形中心是否在非洲边界内,确保只保留有效网格 - Trace替换:直接更新原hexbin的Trace数据,保留原有样式和交互特性
内容的提问来源于stack exchange,提问作者Chopin
相关产品推荐
相关产品推荐

