如何使用底图绘制以太平洋为中心的 shapefile?

How to plot a shapefile centered in the Pacific with Basemap?

当使用 Basemap 的 readshapefile 绘图时,如果定义的地图在 shapefile 的纵向中心以外的任何地方居中,则只绘制它的一部分。这是一个使用 Natural Earth's 海岸线的示例:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

shpf = './NaturalEarth/ne_50m_land/ne_50m_land'

fig, ax = plt.subplots(nrows=1, ncols=1, dpi=100)

m = Basemap(
    ax = ax,
    projection = 'cyl',
    llcrnrlon = 0, llcrnrlat = -90,
    urcrnrlon = 360, urcrnrlat = 90
) 

m.readshapefile(shpf,'ne_50m_land')

m.drawmeridians(np.arange(0,360,45),labels=[True,False,False,True])

产生:

底图或 Python 是否有解决此问题的方法?我知道有些人会在 QGIS 或类似软件中重新居中 shapefile,但每次创建新地图时都这样做似乎不切实际,而且我的 QGIS 技能非常基础。

一种方法是告诉 readshapefile 不要直接绘制海岸线,然后在自己绘制之前操纵线段。这是一个基于您的用例的示例:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

shpf = 'shapefiles/ne_50m_land'

fig, ax = plt.subplots(nrows=1, ncols=1, dpi=100)

m = Basemap(
    ax = ax,
    projection = 'cyl',
    llcrnrlon = 0, llcrnrlat = -90,
    urcrnrlon = 360, urcrnrlat = 90
) 

m.readshapefile(shpf,'ne_50m_land', drawbounds = False)

boundary = 0.0

for info, shape in zip(m.ne_50m_land_info, m.ne_50m_land):
    lons, lats = map(np.array, zip(*shape))

    sep = (lons <= boundary).astype(int)
    roots = np.where(sep[:-1]+sep[1:] == 1)[0]+1
    lower = np.concatenate([[0],roots]).astype(int)
    upper = np.concatenate([roots,[len(lons)]]).astype(int)

    for low, high in zip(lower,upper):
        lo_patch = lons[low:high]
        la_patch = lats[low:high]
        lo_patch[lo_patch<0] += 360
        x,y = m(lo_patch,la_patch)
        ax.plot(x,y,'k',lw=0.5)

m.drawmeridians(np.arange(0,360,45),labels=[True,False,False,True])

plt.show()

在上面的示例中,我按照 Basemap documentation. First I thought it would be enough to just add 360 to each point with a longitude smaller 0, but then you would get horizontal lines whenever a coast line crosses the 0 degree line. So, instead, one has to cut the lines into smaller segments whenever such a crossing appears. This is quite easily accomplished with numpy. I then use the plot command to draw the coast lines. If you want to do something more complex have a look at the Basemap documentation 中解释的方式遍历形状文件的线段。

最终结果如下所示:

希望这对您有所帮助。