Search code examples
python-3.xmatplotlibcartopy

Borders and coastlines interfering in Python Cartopy


I'm trying to draw a map of France using Cartopy, and I'm not very comfortable with it.

Searching for Python code here and there on the Internet, I built the following program:

import cartopy
import cartopy.feature as cfeature
import cartopy.crs as ccrs

import numpy as np

extent = [-4.25, 7.5, 42.25, 51]
central_lon = np.mean(extent[:2])
central_lat = np.mean(extent[2:])

plt.figure(figsize=(8, 8))

ax = plt.axes(projection=ccrs.AlbersEqualArea(central_lon, central_lat))

ax.set_extent(extent)
ax.gridlines()

rivers_50m = cfeature.NaturalEarthFeature('physical', 'rivers_lake_centerlines', '50m')

ax.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=1)
ax.add_feature(cartopy.feature.OCEAN,facecolor=("lightblue"))
ax.add_feature(cartopy.feature.LAND, edgecolor='black')
ax.add_feature(cartopy.feature.LAKES, edgecolor='black')
ax.add_feature(rivers_50m, facecolor='None', edgecolor='blue', linestyle=':')
ax.coastlines(resolution='10m', color='red', linestyle='-', alpha=1)

plt.show()

Which leads to the following map: enter image description here

It's almost what I want, but... I don't understand why the raw borders (the dark broken lines) interfere with the coastlines (the wavy red lines) along the seafront, which is really ugly.

What would be the way to remedy this? (knowing that I would like to keep the terrestrial borders as they are).


Solution

  • Here is the runnable code. All the features that are plotted now has the same scale or resolution. The available scales are: 110m, 50m, 10m.

    import matplotlib.pyplot as plt
    import cartopy
    import cartopy.feature as cfeature
    import cartopy.crs as ccrs
    import numpy as np
    
    extent = [-4.25, 7.5, 42.25, 51]
    central_lon = np.mean(extent[:2])
    central_lat = np.mean(extent[2:])
    
    plt.figure(figsize=(8, 8))
    
    ax = plt.axes(projection=ccrs.AlbersEqualArea(central_lon, central_lat))
    ax.set_extent(extent)
    ax.gridlines()
    
    resol = '50m'  # use data at this scale
    bodr = cartopy.feature.NaturalEarthFeature(category='cultural', 
        name='admin_0_boundary_lines_land', scale=resol, facecolor='none', alpha=0.7)
    land = cartopy.feature.NaturalEarthFeature('physical', 'land', \
        scale=resol, edgecolor='k', facecolor=cfeature.COLORS['land'])
    ocean = cartopy.feature.NaturalEarthFeature('physical', 'ocean', \
        scale=resol, edgecolor='none', facecolor=cfeature.COLORS['water'])
    lakes = cartopy.feature.NaturalEarthFeature('physical', 'lakes', \
        scale=resol, edgecolor='b', facecolor=cfeature.COLORS['water'])
    rivers = cartopy.feature.NaturalEarthFeature('physical', 'rivers_lake_centerlines', \
        scale=resol, edgecolor='b', facecolor='none')
    
    ax.add_feature(land, facecolor='beige')
    ax.add_feature(ocean, linewidth=0.2 )
    ax.add_feature(lakes)
    ax.add_feature(rivers, linewidth=0.5)
    ax.add_feature(bodr, linestyle='--', edgecolor='k', alpha=1)
    
    plt.show()
    

    And the plot:

    enter image description here