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?
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()