Python Basemap经度约定问题:如何绘制跨180°的印尼-太平洋构造边界
Hey there! I get where you're coming from—switching from GMT to Basemap can have little quirks like this, especially with longitude conventions. The core issue here is that the tectonic plate shapefile uses 0-360° longitude, while Basemap expects -180-180° for seamless cross-180° plotting. You don't need to split the readshapefile call twice—here are two straightforward fixes:
Option 1: Preprocess the Shapefile Coordinates (Recommended for Reuse)
If you want a reusable fix, convert the shapefile's longitude range to -180-180° once using geopandas (it's simpler than manual coordinate editing):
import geopandas as gpd from mpl_toolkits.basemap import Basemap import numpy as np import matplotlib.pyplot as plt # Load the tectonic boundary shapefile gdf = gpd.read_file('tectonicplates-master/PB2002_boundaries.shp') # Convert 0-360° longitude to -180-180° def adjust_lon(geometry): # Iterate over every coordinate pair in the geometry corrected_coords = [] for lon, lat in geometry.coords: if lon > 180: corrected_coords.append((lon - 360, lat)) else: corrected_coords.append((lon, lat)) # Return the corrected geometry return type(geometry)(corrected_coords) gdf['geometry'] = gdf['geometry'].apply(adjust_lon) # Optional: Save the corrected shapefile for future use # gdf.to_file('PB2002_boundaries_180.shp') # Set up your Basemap (note: using -160 instead of 220 for urcrnrlon makes the range clearer) plt.figure(figsize=(12, 8)) m = Basemap(llcrnrlon=90., urcrnrlon=-160., llcrnrlat=-30., urcrnrlat=70., resolution='h', projection='gall', lon_0=-35) # lon_0 set to the region's center # Draw base map elements m.drawcoastlines() m.drawparallels(np.arange(-30, 65, 20), labels=[1, 0, 0, 0]) m.drawmeridians(np.arange(90, -150, -30), labels=[0, 0, 0, 1]) # Adjusted to show relevant meridians # Plot the corrected tectonic boundaries for geom in gdf['geometry']: x, y = m(*zip(*geom.coords)) m.plot(x, y, color='blue', zorder=2, linewidth=1.5) plt.show()
Option 2: Edit Coordinates After Reading with Basemap
If you don't want to install geopandas, you can directly modify the shape data Basemap loads, then plot manually:
from mpl_toolkits.basemap import Basemap import numpy as np import matplotlib.pyplot as plt plt.figure(figsize=(12, 8)) # Keep your original Basemap setup if you prefer m = Basemap(llcrnrlon=90., urcrnrlon=220., llcrnrlat=-30., urcrnrlat=70., resolution='h', projection='gall', lon_0=240., lat_0=20.) # Read the shapefile without drawing it immediately m.readshapefile('tectonicplates-master/PB2002_boundaries', name='Pacific', drawbounds=False) # Correct each shape's coordinates and plot for shape in m.Pacific: # Convert any longitude >180 to the -180 range corrected_coords = [(lon - 360 if lon > 180 else lon, lat) for lon, lat in shape] # Convert to Basemap's projection and plot x, y = m(*zip(*corrected_coords)) m.plot(x, y, color='blue', zorder=2, linewidth=1.5) # Draw base map elements m.drawcoastlines() m.drawparallels(np.arange(-30, 65, 20), labels=[1, 0, 0, 0]) m.drawmeridians(np.arange(90, 220, 30), labels=[0, 0, 0, 1]) plt.show()
Why Your Original Code Didn't Work
The tectonic plate shapefile uses 0-360° longitude, so a boundary crossing 180° (e.g., from 190° to 170°) is interpreted by Basemap as a line from 190° east to 170° east—instead of wrapping around to -170° west. This creates a broken or invisible line because it's drawn across the entire map instead of the intended cross-180° segment.
Both fixes above adjust the longitude values to match Basemap's expected range, so the cross-180° boundaries plot correctly.
内容的提问来源于stack exchange,提问作者EmilieK

