如何在Python中使用OSMnx实现水体区域填充?
解决OSMnx绘制填充水体区域的问题
你说得太对了,面向多边形的绘图方法就是正确方向!你当前用graph_from_bbox获取的其实是水体的线状要素(比如海岸线、河流的边线),所以plot_graph只能画出轮廓线条,没法实现填充效果。要搞定填充,核心是获取OpenStreetMap里的面状水体要素,再用面类绘图工具处理。
具体实现步骤
1. 替换获取数据的方式:用geometries_from_bbox获取面状水体
graph_from_bbox是专门用来抓取道路/铁路这类网络数据的,返回的是NetworkX图结构,全是线状要素。我们需要用geometries_from_bbox来获取OpenStreetMap中的面状地理要素,比如湖泊、海域的多边形。
import osmnx as ox import matplotlib.pyplot as plt # 获取纽约市区域的水体多边形(只筛选natural=water的面状要素) water_gdf = ox.geometries_from_bbox( 40.9666, 40.4362, -73.6084, -74.3254, tags={"natural": "water"} ) # 过滤只保留多边形/复合多边形(排除可能混入的点、线要素) water_gdf = water_gdf[water_gdf.geometry.type.isin(["Polygon", "MultiPolygon"])]
2. 绘制填充的水体区域
这里有两种常用方式,选哪种都可以:
方式一:直接用GeoDataFrame的plot方法(灵活度更高)
这种方法可以轻松和道路网络叠加绘制:
# 创建绘图画布和坐标轴 fig, ax = plt.subplots(figsize=(10, 10)) # 绘制填充水体:设置填充色、边线颜色和宽度 water_gdf.plot( ax=ax, facecolor="#add8e6", # 浅蓝填充色 edgecolor="#87ceeb", # 稍深的边线色 linewidth=0.5 ) # (可选)叠加道路网络 road_graph = ox.graph_from_bbox( 40.9666, 40.4362, -73.6084, -74.3254, network_type="drive" ) ox.plot_graph( road_graph, ax=ax, bgcolor="white", node_size=0, # 隐藏节点 edge_color="gray", edge_linewidth=0.8, show=False, # 不单独显示道路图 close=False # 不关闭画布 ) # 优化绘图效果:隐藏坐标轴,紧凑布局 ax.set_axis_off() plt.tight_layout() plt.show()
方式二:用ox.plot_footprints绘制
如果你不需要叠加其他图层,用这个工具函数更简洁:
ox.plot_footprints( water_gdf, bgcolor="white", color="#add8e6", # 填充色 edge_color="#87ceeb", # 边线色 figsize=(10, 10) )
关键知识点解释
- OpenStreetMap中,
natural=water标签对应的既有面状(比如湖泊、内海)也有线状要素,但我们只需要面状的才能填充;coastline通常是线状的,适合画轮廓但没法填充,所以如果不需要海岸线轮廓,可以不用包含它。 geometries_from_bbox返回的是GeoDataFrame,这是处理面状地理数据的标准格式,支持直接用matplotlib或geopandas的绘图工具进行填充、配色等操作。
内容的提问来源于stack exchange,提问作者Michael Toth
相关产品推荐
相关产品推荐

