我在使用 matplotlib 从 python 模块 osmnx 绘制数据时遇到问题。核心问题似乎是边界框的大小。当我指定一个小框(例如社区)时,我收到一条错误消息。较大的边界框效果很好。 这是我的代码:
import osmnx as ox
import matplotlib.pyplot as plt
import geopandas as gpd
import pandas as pd
import os
def plot_features_bbox(title="", include_water=True, include_roads=True, include_railways=True, include_buildings=True):
# Coordinates Bounding Box
north = 50.954088
south = 50.942151
west = 6.913769
east = 6.927888
#dpi
dpi = 400
# Initialize an empty GeoDataFrame
features = gpd.GeoDataFrame()
# Get the water bodies if requested
if include_water:
# Use the common bounding box
water = ox.geometries_from_bbox(north, south, east, west, tags={'natural': 'water'})
features = pd.concat([features, water])
# Get the roads if requested
if include_roads:
# Use the common bounding box
G = ox.graph_from_bbox(north, south, east, west, network_type='drive', simplify=True, truncate_by_edge=True)
roads_gdf = ox.graph_to_gdfs(G, nodes=False)
features = pd.concat([features, roads_gdf])
# Get the railways if requested
if include_railways:
# Use the common bounding box
railways = ox.graph_from_bbox(north, south, east, west, network_type='all',
simplify=True, retain_all=True, truncate_by_edge=True,
clean_periphery=False, custom_filter='["railway"~"rail"]')
railways_gdf = ox.graph_to_gdfs(railways, nodes=False)
features = pd.concat([features, railways_gdf])
# Set colors and linewidths for water, roads, railways, and buildings
water_color = '#5882FA'
road_color = '#688A08'
railway_color = '#848484'
building_color = '#FE9A2E'
road_linewidth = 4.8
railway_linewidth = 2.0
# Plot the selected features within the specified distance around the centerpoint
fig, ax = ox.plot_footprints(features, bbox=(north, south, east, west), figsize=(80, 30),
dpi=dpi, ax=None, color=water_color, bgcolor="#FBFBEF", alpha=None, save=False, show=False, close=False)
if include_roads:
ox.plot_graph(G, ax=ax, node_size=0, bbox = (north, south, east, west), edge_color=road_color, edge_linewidth=road_linewidth,
bgcolor="#FBFBEF", show=False, close=False)
if include_railways:
ox.plot_graph(railways, ax=ax, bbox = (north, south, east, west), edge_color=railway_color, edge_linewidth=railway_linewidth, node_size=0)
# Get building footprints and set their color to the same as other features
if include_buildings:
buildings_gdf = ox.geometries_from_bbox(north, south, east, west, tags={'building': True})
buildings_gdf.plot(ax=ax, facecolor=building_color, alpha=0.7, linewidth=0)
# Add a white background with text
ax.text(0.5, 0.1, title, fontsize=10, ha='center', va='center', transform=ax.transAxes, fontname='Courier New',
bbox=dict(facecolor='white', edgecolor='black', boxstyle='round,pad=0.6'), color='black')
# Add a white border (rectangle) around the map
ax.add_patch(plt.Rectangle((west, south), east - west, north - south, fill=False, color='white', linewidth=50))
fig.tight_layout(pad=0)
# Define the output file path
output_path = r'C:\Users\..'
os.makedirs(output_path, exist_ok=True)
output_filename = os.path.join(output_path, "ehrenfeld.png")
# Save the plot as an image
fig.savefig(output_filename, dpi=dpi, format="png", bbox_inches='tight', facecolor=fig.get_facecolor(), transparent=False)
# Die sichtbare Region auf die Bounding Box beschränken
ax.set_xlim(west, east)
ax.set_ylim(south, north)
# Close the plot
plt.close(fig)
return output_filename
output_filename = plot_features_bbox( title="Hier kann \n dein Text \n stehen.", include_water=True, include_roads=True, include_railways=True, include_buildings=True)
print(f"Die Ausgabe wurde in der Datei '{output_filename}' gespeichert.")
这里的错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[24], line 96
91 plt.close(fig)
93 return output_filename
---> 96 output_filename = plot_features_bbox( title="Hier kann \n dein Text \n stehen.", include_water=True, include_roads=True, include_railways=True, include_buildings=True)
97 print(f"Die Ausgabe wurde in der Datei '{output_filename}' gespeichert.")
Cell In[24], line 55, in plot_features_bbox(title, include_water, include_roads, include_railways, include_buildings)
52 railway_linewidth = 2.0
54 # Plot the selected features within the specified distance around the centerpoint
---> 55 fig, ax = ox.plot_footprints(features, bbox=(north, south, east, west), figsize=(80, 30),
56 dpi=dpi, ax=None, color=water_color, bgcolor="#FBFBEF", alpha=None, save=False, show=False, close=False)
58 if include_roads:
59 ox.plot_graph(G, ax=ax, node_size=0, bbox = (north, south, east, west), edge_color=road_color, edge_linewidth=road_linewidth,
60 bgcolor="#FBFBEF", show=False, close=False)
File ~\anaconda\envs\osmnx\lib\site-packages\osmnx\plot.py:623, in plot_footprints(gdf, ax, figsize, color, edge_color, edge_linewidth, alpha, bgcolor, bbox, save, show, close, filepath, dpi)
621 # retain only Polygons and MultiPolygons, then plot
622 gdf = gdf[gdf["geometry"].type.isin({"Polygon", "MultiPolygon"})]
--> 623 ax = gdf.plot(
624 ax=ax, facecolor=color, edgecolor=edge_color, linewidth=edge_linewidth, alpha=alpha
625 )
627 # determine figure extents
628 if bbox is None:
File ~\anaconda\envs\osmnx\lib\site-packages\geopandas\plotting.py:969, in GeoplotAccessor.__call__(self, *args, **kwargs)
967 kind = kwargs.pop("kind", "geo")
968 if kind == "geo":
--> 969 return plot_dataframe(data, *args, **kwargs)
970 if kind in self._pandas_kinds:
971 # Access pandas plots
972 return PlotAccessor(data)(kind=kind, **kwargs)
File ~\anaconda\envs\osmnx\lib\site-packages\geopandas\plotting.py:681, in plot_dataframe(df, column, cmap, color, ax, cax, categorical, legend, scheme, k, vmin, vmax, markersize, figsize, legend_kwds, categories, classification_kwds, missing_kwds, aspect, **style_kwds)
679 bounds = df.total_bounds
680 y_coord = np.mean([bounds[1], bounds[3]])
--> 681 ax.set_aspect(1 / np.cos(y_coord * np.pi / 180))
682 # formula ported from R package sp
683 # https://github.com/edzer/sp/blob/master/R/mapasp.R
684 else:
685 ax.set_aspect("equal")
File ~\anaconda\envs\osmnx\lib\site-packages\matplotlib\axes\_base.py:1669, in _AxesBase.set_aspect(self, aspect, adjustable, anchor, share)
1667 aspect = float(aspect) # raise ValueError if necessary
1668 if aspect <= 0 or not np.isfinite(aspect):
-> 1669 raise ValueError("aspect must be finite and positive ")
1671 if share:
1672 axes = {sibling for name in self._axis_names
1673 for sibling in self._shared_axes[name].get_siblings(self)}
ValueError: aspect must be finite and positive
我想创建数据的 png 图像文件。除了道路之外,还显示建筑物、水道和铁轨。
基于此 example,
features
不是传递给 ox.plot_footprints
的正确对象。它适用于 gdf_proj = ox.project_gdf(features)
和 fig, ax = ox.plot_footprints(gdf_proj, ...)
。
import osmnx as ox
import geopandas as gpd
import pandas as pd
# Coordinates Bounding Box
north = 50.954088
south = 50.942151
west = 6.913769
east = 6.927888
# get roads
G = ox.graph_from_bbox(north, south, east, west, network_type='drive', simplify=True, truncate_by_edge=True)
roads_gdf = ox.graph_to_gdfs(G, nodes=False)
# get railways
railways = ox.graph_from_bbox(north, south, east, west, network_type='all', simplify=True, retain_all=True, truncate_by_edge=True, custom_filter='["railway"~"rail"]')
railways_gdf = ox.graph_to_gdfs(railways, nodes=False)
# get buildings
buildings_gdf = ox.features_from_bbox(north, south, east, west, tags={'building': True})
# combine the dataframes
features = pd.concat([features, roads_gdf, railways_gdf, buildings_gdf])
# this was the missing element: Reproject a GeoDataFrame
gdf_proj = ox.project_gdf(features)
# Set colors and linewidths for water, roads, railways, and buildings
water_color = '#5882FA'
road_color = '#688A08'
railway_color = '#848484'
building_color = '#FE9A2E'
road_linewidth = 4.8
railway_linewidth = 2.0
# plot gdf_proj, not features
fig, ax = ox.plot_footprints(gdf_proj, bbox=(north, south, east, west), figsize=(80, 30), dpi=400, ax=None, color=water_color, bgcolor="#FBFBEF", alpha=None, save=False, show=False, close=False)
# add the building
buildings_gdf.plot(ax=ax, facecolor=building_color, alpha=0.7, linewidth=0)
# add the roads
ox.plot_graph(G, ax=ax, node_size=0, bbox = (north, south, east, west), edge_color=road_color, edge_linewidth=road_linewidth, bgcolor="#FBFBEF", show=False, close=False)
# add the railway
ox.plot_graph(railways, ax=ax, bbox = (north, south, east, west), edge_color=railway_color, edge_linewidth=railway_linewidth, node_size=0)
fig.savefig('map.png', bbox_inches='tight', pad_inches=0)