How to reduce unnecessary white spaces in matplotlib subplot2grid?

I’m creating some plots with histograms and a color bar, but I’m struggling with the huge white gaps between subplots and I don’t know how to reduce them. This an example of a more complex code:

import numpy as np
import matplotlib.pyplot as plt

ihist = np.array([
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
])

vhist = np.array([
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
])


mins = [1014.3484983803353, -168.92777938399416]
maxs = [5420.578637599565, 1229.7294914536292]
labels = ['x ($\AA$)', 'y ($\AA$)']

fig = plt.figure()
# SIAs
iax = plt.subplot2grid((9, 2), (1, 0), rowspan=8)
iax.set_xlabel(labels[0])
iax.set_xlim(mins[0], maxs[0])
iax.set_ylabel(labels[1])
iax.set_ylim(mins[1], maxs[1])
iax.imshow(ihist, origin="lower", extent=[mins[0], maxs[0], mins[1], maxs[1]])
# Vacancies
vax = plt.subplot2grid((9, 2), (1, 1), rowspan=8)
vax.set_xlabel(labels[0])
vax.set_xlim(mins[0], maxs[0])
vax.set_ylabel(labels[1])
vax.set_ylim(mins[1], maxs[1])
vax.yaxis.set_label_position("right")
vax.yaxis.tick_right()
vax_img = vax.imshow(vhist, origin="lower", extent=[mins[0], maxs[0], mins[1], maxs[1]])
# Color bar
cax = plt.subplot2grid((9, 2), (0, 0), colspan=2)
cbar = fig.colorbar(vax_img, cax=cax, orientation="horizontal")
cbar.set_label("Counts per ion")
cbar.ax.xaxis.set_ticks_position("top")
cbar.ax.xaxis.set_label_position("top")
plt.tight_layout()
plt.show()

And this is the output:

as you can see there are unnecessary white spaces between the color bar and the histograms, and between the histograms and the bottom of the figure. I want to remove them.

I think they are caused by things like plt.subplot2grid((9, 2), (1, 0), rowspan=8) but I did it that way to reduce the vertical size of the color bar.

Note: in the real code, limits are obtained on the fly, so histograms might have same hight and width or not.

This is due to the aspect ratio setting of imshow. If you use:

...
iax.imshow(ihist, origin="lower", extent=[mins[0], maxs[0], mins[1], maxs[1]], aspect="auto")

...
vax_img = vax.imshow(vhist, origin="lower", extent=[mins[0], maxs[0], mins[1], maxs[1]], aspect="auto")

i.e., add aspect="auto", to your imshow calls, it should look as you expect. Note that you may want to switch to using add_gridspec and add_subplot, to allow finer degrees of control over the grid. E.g., an equivalent would be:

...
fig = plt.figure()
# SIAs

# add a two by two grid using the required height ratios
gs = fig.add_gridspec(
    2, 2, height_ratios=(1, 9)
)

iax = fig.add_subplot(gs[1, 0])
iax.set_xlabel(labels[0])
iax.set_xlim(mins[0], maxs[0])
iax.set_ylabel(labels[1])
iax.set_ylim(mins[1], maxs[1])
iax.imshow(ihist, origin="lower", extent=[mins[0], maxs[0], mins[1], maxs[1]], aspect="auto")

# Vacancies
vax = fig.add_subplot(gs[1, 1])
vax.set_xlabel(labels[0])
vax.set_xlim(mins[0], maxs[0])
vax.set_ylabel(labels[1])
vax.set_ylim(mins[1], maxs[1])
vax.yaxis.set_label_position("right")
vax.yaxis.tick_right()
vax_img = vax.imshow(vhist, origin="lower", extent=[mins[0], maxs[0], mins[1], maxs[1]], aspect="auto")

# Color bar
cax = fig.add_subplot(gs[0, :])
cbar = fig.colorbar(vax_img, cax=cax, orientation="horizontal")
cbar.set_label("Counts per ion")
cbar.ax.xaxis.set_ticks_position("top")
cbar.ax.xaxis.set_label_position("top")

# also try constrained layout rather than tight layout
fig.set_layout_engine("constrained")
plt.show()

Suggest using layout='compressed', setting at the beginning, and using the fact that colorbars can be added directly with fig.colorbar(im, ax=axs, location='top'):

There will still be substantial white space because of the aspect ratio of your axes, but the white space will be on the outside of the figure where it is easy to trim, rather than between your colorbar and your axes. Note that if you want to trim this space, it is possible to use fig.savefig('name.png', bbox_inches='tight')

import numpy as np
import matplotlib.pyplot as plt

...

mins = [1014.3484983803353, -168.92777938399416]
maxs = [5420.578637599565, 1229.7294914536292]
labels = ['x ($\AA$)', 'y ($\AA$)']

fig, axs = plt.subplots(1, 2, layout='compressed')
iax = axs[0]
vax = axs[1]

iax.set_xlabel(labels[0])
iax.set_xlim(mins[0], maxs[0])
iax.set_ylabel(labels[1])
iax.set_ylim(mins[1], maxs[1])
iax.imshow(ihist, origin="lower", extent=[mins[0], maxs[0], mins[1], maxs[1]])

# Vacancies
vax.set_xlabel(labels[0])
vax.set_xlim(mins[0], maxs[0])
vax.set_ylabel(labels[1])
vax.set_ylim(mins[1], maxs[1])
vax.yaxis.set_label_position("right")
vax.yaxis.tick_right()
vax_img = vax.imshow(vhist, origin="lower", extent=[mins[0], maxs[0], mins[1], maxs[1]])

# Color bar
cbar = fig.colorbar(vax_img, ax=axs, location="top")
cbar.set_label("Counts per ion")

plt.show()

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật