5

If I define a set of (geo)axes with a given height and width how can I make sure that the plot will fill these axes?

import matplotlib.pyplot as plt
import cartopy.crs as ccrs

ax = plt.axes([0.3, 0.1, 0.4, 0.8], projection=ccrs.PlateCarree())
ax.coastlines()
ax.set_global()
plt.show()

This produces a plot with a sensible aspect ratio for the map, but I wanted it to fill the axes instead, resulting in a plot taller than it is wide. This is just an example, but there are real-world scenarios where doing this is important.

Edit

Just to calrify, I actually want the result to be distorted, so in my example I genuinely want a map with global extent that is taller than it is wide. Using ax.set_aspect('auto') appears to work for PlateCarree and NorthPolarStereographic projections, but perhaps does not work for all (OSGB for example).

ajdawson
  • 3,183
  • 27
  • 36

1 Answers1

10

Good question. I've had this on my radar for quite some months now (https://github.com/SciTools/cartopy/issues/9).

I recently learnt about matplotlib's ax.set_adjustable method (here in fact). Using this allows you to tell an axes which has a fixed (data) aspect ratio to fill the space that it can by changing the data limits.

For example:

import matplotlib.pyplot as plt


ax = plt.axes([0.25, 0.05, 0.5, 0.9])
ax.set_aspect(1)

ax.plot(range(10))
ax.set_adjustable('datalim')

plt.show()

Produces a non-square plot (with equal length scales in the x and y dimensions).

It seems to me that this can be applied to cartopy maps too:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs


ax = plt.axes([0.25, 0.05, 0.5, 0.9], projection=ccrs.PlateCarree())
ax.coastlines()
ax.set_adjustable('datalim')

ax.set_ylim([-90, 90])

plt.show()

I wonder if this suits your needs here?

pelson
  • 21,252
  • 4
  • 92
  • 99
  • 2
    Not exactly. Turns out I just needed to do `ax.set_aspect('auto')` to make this work as I expected. – ajdawson Mar 19 '13 at 12:30
  • Thanks for letting me know. Would you mind adding this as an answer and accept it (or accept my own answer if you like). Cheers – pelson Mar 21 '13 at 16:05
  • `ax.set_aspect('auto')` as suggested by @ajdawson works for me. Maybe @ajdawson could add this as an answer? – Lenka Vraná Apr 14 '19 at 14:29
  • Hi. I am trying to draw the basemap on tkinter canvas and when I am using ax.set_aspect('auto') the map exactly fits the complete canvas area. But the issue is when I am trying to zoom on a particular region of the basemap the map gets stretched. Can anyone just let me know of how to avoid this. – RRSC Jul 23 '20 at 16:02