pythonmatplotlibgeopandascontextily

Goeopandas plot shape and apply opacity outside shape


I am plotting a city boundary (geopandas dataframe) to which I added a basemap using contextily. I would like to apply opacity to the region of the map outside of the city limits. The below example shows the opposite of the desired effect, as the opacity should be applied everywhere except whithin the city limits.

import osmnx as ox
import geopandas as gpd
import contextily as cx

berlin = ox.geocode_to_gdf('Berlin,Germany')
fig, ax = plt.subplots(1, 1, figsize=(10,10))
_ = ax.axis('off')

berlin.plot(ax=ax,
            color='white',
            edgecolor='black',
            alpha=.7,
           )

# basemap 
cx.add_basemap(ax,crs=berlin.crs,)

plt.savefig('stackoverflow_question.png',
            dpi=100,
            bbox_inches='tight',
           )

Plot showing opposite of desired result:
enter image description here


Solution

  • You can create a new polygon that is a buffer on the total bounds of your geometry minus your geometry

    import osmnx as ox
    import geopandas as gpd
    import contextily as cx
    import matplotlib.pyplot as plt
    from shapely.geometry import box
    
    
    berlin = ox.geocode_to_gdf("Berlin,Germany")
    notberlin = gpd.GeoSeries(
        [
            box(*box(*berlin.total_bounds).buffer(0.1).bounds).difference(
                berlin["geometry"].values[0]
            )
        ],
        crs=berlin.crs,
    )
    
    
    fig, ax = plt.subplots(1, 1, figsize=(10, 10))
    _ = ax.axis("off")
    
    notberlin.plot(
        ax=ax,
        color="white",
        edgecolor="black",
        alpha=0.7,
    )
    
    # basemap
    cx.add_basemap(
        ax,
        crs=berlin.crs,
    )
    
    # plt.savefig('stackoverflow_question.png',
    #             dpi=100,
    #             bbox_inches='tight',
    #            )
    

    enter image description here