My goal is to create a poster with a map of travel routs.
You should be able to set the poster size, i.e figure size.
Then you provide a list of long/lat points. Whether or not the poster should be horizontal or vertical should be up to the script, i.e what fits the lat/long provided.
It should then return the poster as a pdf, zoomed in on the relevant part of the map, while still filling the entire canvas. It’s been the last part I have struggled with for days. I guess the extend of the entire map needs to be changed to fit with the ratio of the poster size, but I haven’t been able to do so. Any suggestions would be much obliged ! PS. Im aware of (bbox_inches='tight'), but it ruins the total poster size.
Example script:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import numpy as np
# Define the geographic locations (longitude, latitude)
points = np.array([
(18.4241, -33.9249),
(9.5375, 33.8869),
(-16.3151, 28.4682),
(-9.1393, 38.7223),
(-3.7038, 40.4168),
(2.3522, 48.8566),
(10.7522, 59.9139),
])
# Create figure and add a map in Mercator projection
fig, ax = plt.subplots(figsize=(10, 10), subplot_kw={'projection': ccrs.Mercator()})
# Calculate bounds
lon_min, lat_min = points.min(axis=0) - 1
lon_max, lat_max = points.max(axis=0) + 1
# Set extent based on points
ax.set_extent([lon_min, lon_max, lat_min, lat_max], crs=ccrs.PlateCarree())
# Plot points
ax.scatter(points[:, 0], points[:, 1], marker='o', color='red', transform=ccrs.Geodetic())
# Add coastlines for reference
ax.coastlines()
# Save the plot as a PDF
plt.savefig("map.pdf")
You can use constrained layout to make an axes fill the figure, and set_adjustable to make the data limits update so that the map is the right shape for the expanded axes:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import numpy as np
# Define the geographic locations (longitude, latitude)
points = np.array([
(18.4241, -33.9249),
(9.5375, 33.8869),
(-16.3151, 28.4682),
(-9.1393, 38.7223),
(-3.7038, 40.4168),
(2.3522, 48.8566),
(10.7522, 59.9139),
])
# Create figure and add a map in Mercator projection
fig, ax = plt.subplots(figsize=(10, 10), subplot_kw={'projection': ccrs.Mercator()},
layout='constrained')
# Calculate bounds
lon_min, lat_min = points.min(axis=0) - 1
lon_max, lat_max = points.max(axis=0) + 1
# Set extent based on points
ax.set_extent([lon_min, lon_max, lat_min, lat_max], crs=ccrs.PlateCarree())
# Adjust the data limits so that the map fills the figure without stretching
ax.set_adjustable(adjustable='datalim')
# Plot points
ax.scatter(points[:, 0], points[:, 1], marker='o', color='red', transform=ccrs.Geodetic())
# Add coastlines for reference
ax.coastlines()
# Save the plot as a png (for StackOverflow example)
plt.savefig("map.png")