Skip to content
Advertisement

How to find the right cartopy projection?

I need to plot some data in Germany with cartopy. The data part of my plot works fine (so I deleted it for now). Unfortunately, the shape of the country is deformed due to the projection.

I am currently using the PlateCarree projection, but changing it to Orthographic or others created the same plot.

How to improve the shape?

Link to image of output vs. wanted output

Code:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.io import shapereader

# get country borders
resolution = '10m'
category = 'cultural'
name = 'admin_0_countries'
shpfilename = shapereader.natural_earth(resolution, category, name)
df = geopandas.read_file(shpfilename)
poly = df.loc[df['ADMIN'] == 'Germany']['geometry'].values[0]

# plot
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_extent([5.8, 15.1, 47.25, 55.1],
              crs=ccrs.PlateCarree())
ax.add_geometries(poly,
                  crs=ccrs.PlateCarree(),
                  facecolor='gainsboro',
                  edgecolor='slategray',
                  lw=0.1,
                  alpha=.8)

# save plot
save_path = 'germany.png'
plt.savefig(save_path, dpi=250, bbox_inches='tight', pad_inches=0.)
plt.close()

Advertisement

Answer

The solution is transforming the Geopandas Dataframe using the same projection as explained here

New output: germany.png

New code:

    import matplotlib.pyplot as plt
    import cartopy.crs as ccrs
    import geopandas
    from cartopy.io import shapereader

    # get country borders
    resolution = "10m"
    category = "cultural"
    name = "admin_0_countries"
    shpfilename = shapereader.natural_earth(resolution, category, name)
    df = geopandas.read_file(shpfilename)
    df_de = df.loc[df["ADMIN"] == "Germany"]


    extent = [6., 14.8, 47.1, 55.1]

    # plot
    crs = ccrs.Orthographic(
        central_longitude=(0.5 * (extent[0] + extent[1])),
        central_latitude=(0.5 * (extent[2] + extent[3])),
    )

    crs_proj4 = crs.proj4_init

    df_de.crs = "EPSG:4326"
    df_ae = df_de.to_crs(crs_proj4)

    fig, ax = plt.subplots(subplot_kw={"projection": crs})
    ax.set_extent(extent)
    ax.add_geometries(
        df_ae["geometry"],
        crs=crs,
        facecolor="gainsboro",
        edgecolor="slategray",
        lw=0.1,
        alpha=0.8,
    )

    # save plot
    save_path = "germany.png"
    plt.savefig(save_path, dpi=250, bbox_inches="tight", pad_inches=0.0)
    plt.close()
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement