You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Basemap经度约定问题:如何绘制跨180°的印尼-太平洋构造边界

Solution for Tectonic Boundaries Crossing 180° in Basemap

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:


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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 16:42:38