Python 2.7中Matplotlib Basemap结合Shapefile绘图报错求助
Hey there! Let's tackle this problem step by step—you're already halfway there with Basemap set up for your German city, so let's fix that Shapefile error first, then walk through the full workflow to get your roads and service points mapped properly.
That truncated RuntimeError: Can not pu... is almost certainly a "Can not open shapefile" issue, which usually boils down to a few common problems:
- Missing Shapefile components: Shapefiles aren't single files—they rely on a set of core files (
.shpfor geometry,.shxfor indexing,.dbffor attributes) all in the same folder, with identical filenames (only suffixes differ). Double-check that all three are present and haven't been renamed or moved. - Incorrect file path: Python 2.7 can struggle with relative paths or paths containing special characters (like German umlauts
ä/ö/ü). Use an absolute path, and if you have special characters, wrap the path in a Unicode string:from mpl_toolkits.basemap import Basemap import matplotlib.pyplot as plt # Initialize your map with your city's coordinates city_map = Basemap(llcrnrlon=YOUR_MIN_LON, llcrnrlat=YOUR_MIN_LAT, urcrnrlon=YOUR_MAX_LON, urcrnrlat=YOUR_MAX_LAT, projection='merc') # Use absolute Unicode path (omit the .shp suffix—Basemap auto-discovers related files) shapefile_path = u'/full/path/to/your/german_city_roads' city_map.readshapefile(shapefile_path, 'city_roads') - Permission issues: Make sure your Python script has read access to the folder containing the Shapefile.
Once the Shapefile error is fixed, here's a complete, step-by-step implementation tailored to your project:
Initialize your Basemap with city bounds
Replace the coordinates with your target city's min/max longitude/latitude:city_map = Basemap( llcrnrlon=11.3, llcrnrlat=48.08, # Example: Munich's southwest bounds urcrnrlon=11.7, urcrnrlat=48.25, # Example: Munich's northeast bounds projection='merc', resolution='i' # 'i' = intermediate resolution (good for city-level maps) )Draw the road network
After reading the Shapefile, loop through the geometry data to plot each road:# Load and plot roads city_map.readshapefile('/path/to/your/roads_shapefile', 'city_roads') for road in city_map.city_roads: x_coords, y_coords = zip(*road) city_map.plot(x_coords, y_coords, color='darkgray', linewidth=0.6)Add service point markers and labels
Assume you have a list of service points with names, longitudes, and latitudes—plot them as visible markers with text labels:# Example service point data (replace with your actual data) service_points = [ ('Central Station', 11.5755, 48.1374), ('City Hospital', 11.5823, 48.1456), ('Main Library', 11.5689, 48.1298) ] # Plot each service point for name, lon, lat in service_points: x, y = city_map(lon, lat) city_map.plot(x, y, 'ro', markersize=8, alpha=0.8) # Red circle marker plt.text(x + 150, y + 150, name, fontsize=9) # Offset text to avoid covering markersAdd polished map elements (optional but recommended)
Make your map more readable with boundaries, water features, and coordinate ticks:city_map.drawmapboundary(fill_color='lightskyblue') city_map.fillcontinents(color='wheat', lake_color='lightskyblue') city_map.drawcountries(linewidth=1.2) city_map.drawparallels(range(48, 49, 0.1), labels=[1,0,0,0]) city_map.drawmeridians(range(11, 12, 0.1), labels=[0,0,0,1])Display or save your map
plt.title('Your German City: Roads & Service Locations') plt.show() # Save as high-res PNG if needed plt.savefig('city_service_map.png', dpi=300, bbox_inches='tight')
- Python 2.7 is end-of-life, so if your project allows, consider upgrading to Python 3.x (modern mapping libraries like Cartopy only support 3.x). But if you must stick with 2.7, ensure you have Basemap v1.2.0 installed (the last version compatible with 2.7).
- If your Shapefile uses a different coordinate system than your Basemap projection, you’ll see misaligned roads. Use a tool like QGIS to check the Shapefile’s CRS, then use
pyprojto convert coordinates to match your Basemap’s projection.
内容的提问来源于stack exchange,提问作者CWhite

