-
Notifications
You must be signed in to change notification settings - Fork 388
Description
Description
I am trying to use the new constrained layout engine from matplotlib in combination with a GeoAxes with gridlines. I can not find a combination that works properly. All combinations I try fail in some way or another, some with poor styling and some with actual crashes.
I need to make plots of a specific size, and I would like the axes, titles, colour bars, etc to fill the available space. A Figure(layout="constrained")
combined with axes.set_aspect("equal", "datalim")
works perfectly for this. The figure is always of the correct size, and the axes are reshaped to fill the figure. By setting the appropriate xlim/ylim, or by using axes.autoscale()
the elements to be plotted are arranged within the axes correctly.
I would also like to include grid lines on the axes. No matter which options I choose, I can not get the grid lines to behave.
Code to reproduce
I installed the latest versions of Python, cartopy, matplotlib:
$ conda install -c conda-forge python cartopy matplotlib
I then added the following to a script and ran it:
#!/usr/bin/env python3
import cartopy.crs
import numpy
from matplotlib import pyplot as plt
from matplotlib.collections import PolyCollection
# Make a figure with a specific size
figure = plt.figure(figsize=(8, 4), layout="constrained")
# Make some axes that will fill the available space while maintaining correct aspect ratio
axes = figure.add_subplot(projection=cartopy.crs.PlateCarree())
axes.set_aspect(aspect='equal', adjustable='datalim')
# Add some polygon to the map, with a colour bar
collection = PolyCollection(
verts=[
[[0, 0], [1, 0], [1, 1], [0, 1]],
[[1, 0], [2, 0], [2, 1], [1, 1]],
[[0, 1], [1, 1], [1, 2], [0, 2]],
[[1, 1], [2, 1], [2, 2], [1, 2]],
],
array=[1, 2, 3, 4],
)
axes.add_collection(collection)
figure.colorbar(collection, ax=axes, location='right', label='index')
# Set up the axes data limits to keep the polygon in view
axes.autoscale()
# Add some gridlines
gridlines = axes.gridlines(draw_labels=["bottom", "left"])
figure.savefig('figure.png')
This results in the grid lines not filling the available space correctly:
My best guess is that the gridlines don't notice that the layout engine has done its thing and so the grid lines are now misplaced.
If I remove the axes.set_aspect(...)
line the gridlines correctly cover the area, but the axes are shrunk to only take up the necessary space leaving a large gap. It would be possible to configure anchor points and etc to arrange this a little nicer, but I want the axes to take up the available space:
If I instead remove the layout="constrained"
from the figure, the plot components do not fill up the entire space. This plot looks the best of the lot, but I would like to make use of the new layout engine.
I tried adding auto_update=True
to the gridlines, and while this does result in the gridlines being adjusted correctly, the labels are now off the edge of the figure:
Full environment definition
Operating system
Ubuntu 20.04
Cartopy version
0.22.0
conda list
# packages in environment at /home/hea211/hecking-around/emsarray/.conda:
#
# Name Version Build Channel
_libgcc_mutex 0.1 conda_forge conda-forge
_openmp_mutex 4.5 2_gnu conda-forge
alsa-lib 1.2.10 hd590300_0 conda-forge
attr 2.5.1 h166bdaf_1 conda-forge
brotli 1.1.0 hd590300_0 conda-forge
brotli-bin 1.1.0 hd590300_0 conda-forge
bzip2 1.0.8 h7f98852_4 conda-forge
c-ares 1.19.1 hd590300_0 conda-forge
ca-certificates 2023.7.22 hbcca054_0 conda-forge
cairo 1.16.0 h0c91306_1017 conda-forge
cartopy 0.22.0 py311h320fe9a_0 conda-forge
certifi 2023.7.22 pyhd8ed1ab_0 conda-forge
contourpy 1.1.1 py311h9547e67_0 conda-forge
cycler 0.11.0 pyhd8ed1ab_0 conda-forge
dbus 1.13.6 h5008d03_3 conda-forge
expat 2.5.0 hcb278e6_1 conda-forge
font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge
font-ttf-inconsolata 3.000 h77eed37_0 conda-forge
font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge
font-ttf-ubuntu 0.83 hab24e00_0 conda-forge
fontconfig 2.14.2 h14ed4e7_0 conda-forge
fonts-conda-ecosystem 1 0 conda-forge
fonts-conda-forge 1 0 conda-forge
fonttools 4.42.1 py311h459d7ec_0 conda-forge
freetype 2.12.1 h267a509_2 conda-forge
geos 3.12.0 h59595ed_0 conda-forge
gettext 0.21.1 h27087fc_0 conda-forge
glib 2.78.0 hfc55251_0 conda-forge
glib-tools 2.78.0 hfc55251_0 conda-forge
graphite2 1.3.13 h58526e2_1001 conda-forge
gst-plugins-base 1.22.5 h8e1006c_1 conda-forge
gstreamer 1.22.5 h98fc4e7_1 conda-forge
harfbuzz 8.2.1 h3d44ed6_0 conda-forge
icu 73.2 h59595ed_0 conda-forge
keyutils 1.6.1 h166bdaf_0 conda-forge
kiwisolver 1.4.5 py311h9547e67_0 conda-forge
krb5 1.21.2 h659d440_0 conda-forge
lame 3.100 h166bdaf_1003 conda-forge
lcms2 2.15 h7f713cb_2 conda-forge
ld_impl_linux-64 2.40 h41732ed_0 conda-forge
lerc 4.0.0 h27087fc_0 conda-forge
libblas 3.9.0 18_linux64_openblas conda-forge
libbrotlicommon 1.1.0 hd590300_0 conda-forge
libbrotlidec 1.1.0 hd590300_0 conda-forge
libbrotlienc 1.1.0 hd590300_0 conda-forge
libcap 2.69 h0f662aa_0 conda-forge
libcblas 3.9.0 18_linux64_openblas conda-forge
libclang 15.0.7 default_h7634d5b_3 conda-forge
libclang13 15.0.7 default_h9986a30_3 conda-forge
libcups 2.3.3 h4637d8d_4 conda-forge
libcurl 8.3.0 hca28451_0 conda-forge
libdeflate 1.19 hd590300_0 conda-forge
libedit 3.1.20191231 he28a2e2_2 conda-forge
libev 4.33 h516909a_1 conda-forge
libevent 2.1.12 hf998b51_1 conda-forge
libexpat 2.5.0 hcb278e6_1 conda-forge
libffi 3.4.2 h7f98852_5 conda-forge
libflac 1.4.3 h59595ed_0 conda-forge
libgcc-ng 13.2.0 h807b86a_1 conda-forge
libgcrypt 1.10.1 h166bdaf_0 conda-forge
libgfortran-ng 13.2.0 h69a702a_1 conda-forge
libgfortran5 13.2.0 ha4646dd_1 conda-forge
libglib 2.78.0 hebfc3b9_0 conda-forge
libgomp 13.2.0 h807b86a_1 conda-forge
libgpg-error 1.47 h71f35ed_0 conda-forge
libiconv 1.17 h166bdaf_0 conda-forge
libjpeg-turbo 2.1.5.1 hd590300_1 conda-forge
liblapack 3.9.0 18_linux64_openblas conda-forge
libllvm15 15.0.7 h5cf9203_3 conda-forge
libnghttp2 1.52.0 h61bc06f_0 conda-forge
libnsl 2.0.0 h7f98852_0 conda-forge
libogg 1.3.4 h7f98852_1 conda-forge
libopenblas 0.3.24 pthreads_h413a1c8_0 conda-forge
libopus 1.3.1 h7f98852_1 conda-forge
libpng 1.6.39 h753d276_0 conda-forge
libpq 15.4 hfc447b1_0 conda-forge
libsndfile 1.2.2 hbc2eb40_0 conda-forge
libsqlite 3.43.0 h2797004_0 conda-forge
libssh2 1.11.0 h0841786_0 conda-forge
libstdcxx-ng 13.2.0 h7e041cc_1 conda-forge
libsystemd0 254 h3516f8a_0 conda-forge
libtiff 4.6.0 h29866fb_1 conda-forge
libuuid 2.38.1 h0b41bf4_0 conda-forge
libvorbis 1.3.7 h9c3ff4c_0 conda-forge
libwebp-base 1.3.2 hd590300_0 conda-forge
libxcb 1.15 h0b41bf4_0 conda-forge
libxkbcommon 1.5.0 h5d7e998_3 conda-forge
libxml2 2.11.5 h232c23b_1 conda-forge
libzlib 1.2.13 hd590300_5 conda-forge
lz4-c 1.9.4 hcb278e6_0 conda-forge
matplotlib 3.8.0 py311h38be061_0 conda-forge
matplotlib-base 3.8.0 py311h54ef318_0 conda-forge
mpg123 1.31.3 hcb278e6_0 conda-forge
munkres 1.1.4 pyh9f0ad1d_0 conda-forge
mysql-common 8.0.33 hf1915f5_4 conda-forge
mysql-libs 8.0.33 hca2cd23_4 conda-forge
ncurses 6.4 hcb278e6_0 conda-forge
nspr 4.35 h27087fc_0 conda-forge
nss 3.92 h1d7d5a4_0 conda-forge
numpy 1.26.0 py311h64a7726_0 conda-forge
openjpeg 2.5.0 h488ebb8_3 conda-forge
openssl 3.1.2 hd590300_0 conda-forge
packaging 23.1 pyhd8ed1ab_0 conda-forge
pcre2 10.40 hc3806b6_0 conda-forge
pillow 10.0.1 py311h8aef010_0 conda-forge
pip 23.2.1 pyhd8ed1ab_0 conda-forge
pixman 0.40.0 h36c2ea0_0 conda-forge
ply 3.11 py_1 conda-forge
proj 8.2.1 ha227179_0
pthread-stubs 0.4 h36c2ea0_1001 conda-forge
pulseaudio-client 16.1 hb77b528_5 conda-forge
pyparsing 3.1.1 pyhd8ed1ab_0 conda-forge
pyproj 3.4.1 py311h93e2b2c_0
pyqt 5.15.9 py311hf0fb5b6_4 conda-forge
pyqt5-sip 12.12.2 py311hb755f60_4 conda-forge
pyshp 2.3.1 pyhd8ed1ab_0 conda-forge
python 3.11.5 hab00c5b_0_cpython conda-forge
python-dateutil 2.8.2 pyhd8ed1ab_0 conda-forge
python_abi 3.11 3_cp311 conda-forge
qt-main 5.15.8 hc47bfe8_16 conda-forge
readline 8.2 h8228510_1 conda-forge
setuptools 68.2.2 pyhd8ed1ab_0 conda-forge
shapely 2.0.1 py311he06c224_2 conda-forge
sip 6.7.11 py311hb755f60_0 conda-forge
six 1.16.0 pyh6c4a22f_0 conda-forge
sqlite 3.43.0 h2c6b66d_0 conda-forge
tk 8.6.12 h27826a3_0 conda-forge
toml 0.10.2 pyhd8ed1ab_0 conda-forge
tomli 2.0.1 pyhd8ed1ab_0 conda-forge
tornado 6.3.3 py311h459d7ec_0 conda-forge
tzdata 2023c h71feb2d_0 conda-forge
wheel 0.41.2 pyhd8ed1ab_0 conda-forge
xcb-util 0.4.0 hd590300_1 conda-forge
xcb-util-image 0.4.0 h8ee46fc_1 conda-forge
xcb-util-keysyms 0.4.0 h8ee46fc_1 conda-forge
xcb-util-renderutil 0.3.9 hd590300_1 conda-forge
xcb-util-wm 0.4.1 h8ee46fc_1 conda-forge
xkeyboard-config 2.39 hd590300_0 conda-forge
xorg-kbproto 1.0.7 h7f98852_1002 conda-forge
xorg-libice 1.1.1 hd590300_0 conda-forge
xorg-libsm 1.2.4 h7391055_0 conda-forge
xorg-libx11 1.8.6 h8ee46fc_0 conda-forge
xorg-libxau 1.0.11 hd590300_0 conda-forge
xorg-libxdmcp 1.1.3 h7f98852_0 conda-forge
xorg-libxext 1.3.4 h0b41bf4_2 conda-forge
xorg-libxrender 0.9.11 hd590300_0 conda-forge
xorg-renderproto 0.11.1 h7f98852_1002 conda-forge
xorg-xextproto 7.3.0 h0b41bf4_1003 conda-forge
xorg-xf86vidmodeproto 2.3.1 h7f98852_1002 conda-forge
xorg-xproto 7.0.31 h7f98852_1007 conda-forge
xz 5.2.6 h166bdaf_0 conda-forge
zlib 1.2.13 hd590300_5 conda-forge
zstd 1.5.5 hfc55251_0 conda-forge