我需要通过水平展开子图来删除某些子图之间的空白区域。
这是一张图片,用两个漂亮的手绘红色圆圈表示我的意思(MWE如下):
通过"摆脱"我的意思是:水平扩展每列中的两个底部子图,这样它们之间几乎没有空白区域。分隔列的空白区域必须保持不变,以避免修改上面的方形子图。
我已经尝试了fig.subplots_adjust(wspace=0)
,但这会弄乱上面的子图,我只需要修改底部子图之间的空白区域。
我还尝试更新了GridSpec as shown here,但这与tight_layout()
并不相符。
MWE
MWE看起来很长,但它只是复制/粘贴相同的代码并进行了少量更改(即:删除刻度,标签,颜色条等)。
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig = plt.figure(figsize=(14.25, 13.5))
gs = gridspec.GridSpec(3, 6)
# Left top plot.
ax1 = plt.subplot(gs[0:1, 0:2])
plt.title('AAAAAAAA', fontsize=11)
ax1.tick_params(axis='both', which='major', labelsize=9)
ax1.set_xticklabels([])
plt.xlabel('', fontsize=12)
plt.ylabel('BBBB', fontsize=12)
SC = plt.scatter([0., 1.], [0., 1.], c=[2., 5.])
# Position colorbar.
the_divider = make_axes_locatable(ax1)
color_axis = the_divider.append_axes("right", size="2%", pad=0.1)
# Colorbar.
cbar = plt.colorbar(SC, cax=color_axis)
cbar.set_label('ccc', fontsize=12, labelpad=4, y=0.5)
cbar.ax.tick_params(labelsize=9)
ax1.set_aspect(aspect='auto')
# Left middle plot.
ax2 = plt.subplot(gs[1:2, 0:2])
ax2.tick_params(axis='both', which='major', labelsize=9)
plt.xlabel('DDDD', fontsize=12)
plt.ylabel('BBBB', fontsize=12)
SC = plt.scatter([10., 5.], [3., 17.], c=[0.3, 0.8])
the_divider = make_axes_locatable(ax2)
color_axis = the_divider.append_axes("right", size="2%", pad=0.1)
cbar = plt.colorbar(SC, cax=color_axis)
cbar.set_label('ccc', fontsize=12, labelpad=4, y=0.5)
cbar.ax.tick_params(labelsize=9)
ax2.set_aspect(aspect='auto')
# Left bottom left plot.
ax3 = plt.subplot(gs[2:3, 0:1])
ax3.tick_params(axis='both', which='major', labelsize=9)
plt.xlabel('DDDD', fontsize=12)
plt.ylabel('BBBB', fontsize=12)
# Left bottom right pot.
ax4 = plt.subplot(gs[2:3, 1:2])
ax4.tick_params(axis='both', which='major', labelsize=9)
ax4.set_yticklabels([])
plt.xlabel('DDDD', fontsize=12)
plt.ylabel('', fontsize=12)
# Middle top plot.
ax5 = plt.subplot(gs[0:1, 2:4])
plt.title('AAAAAAAA', fontsize=11)
ax5.tick_params(axis='both', which='major', labelsize=9)
ax5.set_xticklabels([])
ax5.set_yticklabels([])
plt.xlabel('', fontsize=12)
plt.ylabel('', fontsize=12)
SC = plt.scatter([0., 1.], [0., 1.], c=[2., 5.])
the_divider = make_axes_locatable(ax5)
color_axis = the_divider.append_axes("right", size="2%", pad=0.1)
cbar = plt.colorbar(SC, cax=color_axis)
cbar.set_label('ccc', fontsize=12, labelpad=4, y=0.5)
cbar.ax.tick_params(labelsize=9)
ax5.set_aspect(aspect='auto')
# Middle middle plot.
ax6 = plt.subplot(gs[1:2, 2:4])
ax6.tick_params(axis='both', which='major', labelsize=9)
ax5.set_yticklabels([])
plt.xlabel('DDDD', fontsize=12)
plt.ylabel('', fontsize=12)
SC = plt.scatter([10., 5.], [3., 17.], c=[0.3, 0.8])
the_divider = make_axes_locatable(ax6)
color_axis = the_divider.append_axes("right", size="2%", pad=0.1)
cbar = plt.colorbar(SC, cax=color_axis)
cbar.set_label('ccc', fontsize=12, labelpad=4, y=0.5)
cbar.ax.tick_params(labelsize=9)
ax6.set_aspect(aspect='auto')
# Middle bottom left plot.
ax7 = plt.subplot(gs[2:3, 2:3])
ax7.tick_params(axis='both', which='major', labelsize=9)
ax7.set_yticklabels([])
plt.xlabel('DDDD', fontsize=12)
plt.ylabel('', fontsize=12)
# Middle bottom right pot.
ax8 = plt.subplot(gs[2:3, 3:4])
ax8.tick_params(axis='both', which='major', labelsize=9)
ax8.set_yticklabels([])
plt.xlabel('DDDD', fontsize=12)
plt.ylabel('', fontsize=12)
SC = plt.scatter([10., 5.], [3., 17.], c=[0.3, 0.8])
the_divider = make_axes_locatable(ax8)
color_axis = the_divider.append_axes("right", size="5%", pad=0.1)
cbar = plt.colorbar(SC, cax=color_axis)
cbar.set_label('eee', fontsize=12, labelpad=4, y=0.5)
cbar.ax.tick_params(labelsize=9)
fig.tight_layout()
plt.savefig('del.png', dpi=150)
答案 0 :(得分:0)
我设法使用多个gridspec和GridSpecFromSubplotSpec来或多或少地解决了这个问题。
代码相当可怕而且非常黑客,但它完成了工作。在接受我的回答之前,我会等到有人想出一个不太可怕的解决方案。
代码:
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
def data():
x = np.random.uniform(-10, 10., 50)
y = np.random.uniform(-10, 10., 50)
z = np.random.uniform(0, 1., 50)
return x, y, z
def square_plot(gs, i):
# Define gridspec ranges.
x_gdsp = [[0, 2], [2, 4], [4, 6]]
if i in [0, 1, 2]:
y1, y2 = 0, 1
x1, x2 = x_gdsp[i]
elif i in [3, 4, 5]:
y1, y2 = 1, 2
x1, x2 = x_gdsp[i-3]
ax = plt.subplot(gs[y1:y2, x1:x2])
if i in [0, 1, 2]:
plt.title('AAAAAAAA', fontsize=11)
ax.set_xticklabels([])
if i in [0, 3]:
plt.ylabel('BBBB', fontsize=12)
else:
ax.set_yticklabels([])
if i in [3, 4, 5]:
plt.xlabel('CCCC', fontsize=12)
ax.tick_params(axis='both', which='major', labelsize=9)
x, y, z = data()
SC = plt.scatter(x, y, c=z)
# Position colorbar.
the_divider = make_axes_locatable(ax)
color_axis = the_divider.append_axes("right", size="2%", pad=0.1)
# Colorbar.
cbar = plt.colorbar(SC, cax=color_axis)
cbar.set_label('cbar', fontsize=12, labelpad=4, y=0.5)
cbar.ax.tick_params(labelsize=9)
ax.set_aspect(aspect='auto')
def rectangular_plots(gs, i):
x_gdsp = [[[0, 1], [2, 3], [4, 5]], [[1, 2], [3, 4], [5, 6]]]
y1, y2 = 2, 3
x11, x12 = x_gdsp[0][i]
x21, x22 = x_gdsp[1][i]
# Left plot.
right_gs = gridspec.GridSpecFromSubplotSpec(
1, 2, width_ratios=[1, 6], subplot_spec=gs[y1:y2, x11:x12],
wspace=0.)
ax3 = plt.subplot(right_gs[1])
plt.ylim(-15., 15.)
plt.xlabel('DDDD', fontsize=12)
if i == 0:
ax3.set_ylabel('BBBB', fontsize=12)
else:
ax3.set_yticklabels([])
ax3.tick_params(axis='both', which='major', labelsize=9)
x, y, z = data()
plt.scatter(x, y, c=z)
# Right pot.
right_gs = gridspec.GridSpecFromSubplotSpec(
1, 2, width_ratios=[6, 1], subplot_spec=gs[y1:y2, x21:x22],
wspace=0.)
ax4 = plt.subplot(right_gs[0])
plt.ylim(-15., 15.)
plt.xlabel('DDDD', fontsize=12)
ax4.tick_params(axis='both', which='major', labelsize=9)
ax4.set_yticklabels([])
x, y, z = data()
SC = plt.scatter(x, y, c=z)
the_divider = make_axes_locatable(ax4)
color_axis = the_divider.append_axes("right", size="5%", pad=0.1)
cbar = plt.colorbar(SC, cax=color_axis)
cbar.set_label('eee', fontsize=12, labelpad=4, y=0.5)
cbar.ax.tick_params(labelsize=9)
fig = plt.figure(figsize=(14.25, 13.5))
# Make square plots.
gs = gridspec.GridSpec(3, 6)
for i in range(6):
square_plot(gs, i)
# New gridspecs for bottom rectangular plots.
# ***Values selected by hand***
gs2 = gridspec.GridSpec(3, 6)
gs2.update(wspace=0.0, bottom=0.029, left=0.031, right=0.95)
gs3 = gridspec.GridSpec(3, 6)
gs3.update(wspace=0.0, bottom=0.029, left=0.043, right=0.965)
gs4 = gridspec.GridSpec(3, 6)
gs4.update(wspace=0.0, bottom=0.029, left=0.05, right=0.976)
# Make plots.
rectangular_plots(gs2, 0)
rectangular_plots(gs3, 1)
rectangular_plots(gs4, 2)
fig.tight_layout()
plt.savefig('del.png', dpi=150)