Search code examples
pythonmatplotlibgeopandasshapelycartopy

Buffer line across lon=180 causes banding geopandas matplotlib


I am trying to plot Polygon geometries across the 180 longitude when the map's central_longitude = 180; however there's an artificial banding occurring.

Is there a way to stop matplotlib from banding shown in the red circle?

enter image description here

import matplotlib.pyplot as plt
import geopandas as gpd
import cartopy.crs as ccrs

lats = np.linspace(-75, 75, 100)
lons = np.linspace(150, 190, 100)
gdf = gpd.GeoDataFrame(
    crs=4326, geometry=gpd.points_from_xy(lons, lats)
)
gdf = gdf.to_crs({'init': 'epsg:3174'})
gdf['geometry'] = gdf['geometry'].buffer(90000)
gdf['route'] = 0
gdf = gdf.to_crs({'init': 'EPSG:4326'})

ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
ax.add_geometries(gdf['geometry'], crs=ccrs.PlateCarree())
ax.set_extent([120, 250, -75, 75], crs=ccrs.PlateCarree())
ax.gridlines(draw_labels=True, xlocs=[180])
ax.coastlines()

Solution

  • Reprojecting from epsg:3174 to EPSG:4326 jumbles the geometries crossing dateline. You can plot the geodataframe with epsg:3174 direcly as seen with this code:

    import matplotlib.pyplot as plt
    import geopandas as gpd
    import cartopy.crs as ccrs
    import numpy as np
    
    lats = np.linspace(-75, 75, 100)
    lons = np.linspace(150, 190, 100)
    gdf = gpd.GeoDataFrame(
        crs=4326, geometry=gpd.points_from_xy(lons, lats)
    )
    # gdf2 = gdf.to_crs({'init': 'epsg:3174'})
    gdf2 = gdf.to_crs(epsg=3174)
    gdf2['geometry'] = gdf2['geometry'].buffer(90000)
    gdf2['route'] = 0
    
    ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
    ax.add_geometries(gdf2['geometry'], crs=ccrs.epsg(3174))
    ax.set_extent([120, 250, -75, 75], crs=ccrs.PlateCarree())
    ax.gridlines(draw_labels=True, xlocs=[180])
    ax.coastlines()
    
    plt.show()
    

    route_xing_dateline