两个 imshow 的一个颜色条

One colorbar for two imshows

我有以下代码,但我无法将颜色条放置在不与 imshow 本身重叠的位置,如果我将它放置在更远的地方,它就会被切断:( 我已经尝试了很多东西,但没有解决这个问题。 如果颜色条不是水平的,那对我也适用,但是轴的标签也需要垂直。

帮助

import numpy as np
import matplotlib
import matplotlib.pyplot as plt


vegetables = [ "One magnet", "Two magnets","washer",
              "ST37 - 1", "ST37 - 2", "ST37 - 3", "RVS"]



farmers0 = ["1 cm/s", "1.25 cm/s"]



mask0 = np.array([[False, False, False, False, False, False, False],
                    [False, False, False, True, True, True, True]])

harvest1 = np.array([[ 1.9, 1.6,1.1,1.2,1.1,0.5,0.7],
                    [ 1.6, 0.8,0.9, 0,0,0,0]])

harvest1 = np.ma.array(harvest1, mask=mask0)

harvest2 = np.array([[ 0.9, 1.0,0.7,1.0,1.1,0.4,0.6],
                    [ 0.9, 0.8,0.8, 0,0,0,0]])
harvest2 = np.ma.array(harvest2, mask=mask0)




fig, ax = plt.subplots(2, sharex=True, sharey=False)



im0 = ax[0].imshow(harvest1, cmap='RdYlGn_r', vmin = 0.5, vmax = 1.65)

# We want to show all ticks...
ax[0].set_xticks(np.arange(len(vegetables)))
ax[0].set_yticks(np.arange(len(farmers0)))
# ... and label them with the respective list entries
ax[0].set_xticklabels(vegetables)
ax[0].set_yticklabels(farmers0)


# Rotate the tick labels and set their alignment.
plt.setp(ax[0].get_xticklabels(), rotation=45, ha="right",
         rotation_mode="anchor")



for i in range(len(farmers0)):
    for j in range(len(vegetables)):
        text = ax[0].text(j, i, harvest1[i, j],
                       ha="center", va="center", color="k")
    

im0 = ax[1].imshow(harvest2, cmap='RdYlGn_r', vmin = 0.5, vmax = 1.65)

# We want to show all ticks...
ax[1].set_xticks(np.arange(len(vegetables)))
ax[1].set_yticks(np.arange(len(farmers0)))
# ... and label them with the respective list entries
ax[1].set_xticklabels(vegetables)
ax[1].set_yticklabels(farmers0)


# Rotate the tick labels and set their alignment.
plt.setp(ax[1].get_xticklabels(), rotation=45, ha="right",
         rotation_mode="anchor")



for i in range(len(farmers0)):
    for j in range(len(vegetables)):
        text = ax[1].text(j, i, harvest2[i, j],
                       ha="center", va="center", color="k")
 
#fig.colorbar(im0, ax=ax.ravel().tolist(), orientation = 'horizontal')



#plt.gcf().subplots_adjust(top=1.5)

fig.tight_layout()

cbaxes = fig.add_axes([0.15,0.9,0.82,0.05]) #links, hight
#cax = divider.append.axes("bottom", size= "5%", pad = 0.05)
bar2 = plt.colorbar(im0, cax = cbaxes , orientation = 'horizontal')

bar2.ax.set_title('90 % confidence interval of $d$')



plt.show()

matplotlib 实际上警告您 tight_layout 将无法使用手动添加的轴...

UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect. fig.tight_layout()

使用fig.subplots_adjust手动设置地块的边界!

所以基本上...只需在最后添加这一行就可以了:-)

fig.tight_layout()
fig.subplots_adjust(top=0.8)

也许还可以通过将对 plt.subplots 的调用更改为:

来明确指定图形大小
fig, ax = plt.subplots(2, figsize=(7, 5), sharex=True, sharey=False)

这是一个使用 GridSpec 来更好地控制轴网格的版本(例如,这样您就可以调整颜色条和轴之间的间距等)

另请注意,我在 ax.imshow 调用中使用 aspect='auto' 以允许使用非方形像素!

import numpy as np
import matplotlib
import matplotlib.pyplot as plt

from matplotlib.gridspec import GridSpec, GridSpecFromSubplotSpec

vegetables = [ "One magnet", "Two magnets","washer",
              "ST37 - 1", "ST37 - 2", "ST37 - 3", "RVS"]



farmers0 = ["1 cm/s", "1.25 cm/s"]



mask0 = np.array([[False, False, False, False, False, False, False],
                    [False, False, False, True, True, True, True]])

harvest1 = np.array([[ 1.9, 1.6,1.1,1.2,1.1,0.5,0.7],
                    [ 1.6, 0.8,0.9, 0,0,0,0]])

harvest1 = np.ma.array(harvest1, mask=mask0)

harvest2 = np.array([[ 0.9, 1.0,0.7,1.0,1.1,0.4,0.6],
                    [ 0.9, 0.8,0.8, 0,0,0,0]])
harvest2 = np.ma.array(harvest2, mask=mask0)


# -----------------------------------------------
# manually create an axes to have full control over spacing etc.
gs = GridSpec(2, 1, 
              height_ratios=(.5, 9.5))
gs_ax = GridSpecFromSubplotSpec(2, 1, gs[1], 
                                hspace=.5)

fig = plt.figure(figsize=(7, 7))
ax = []
ax.append(fig.add_subplot(gs_ax[0]))
ax.append(fig.add_subplot(gs_ax[1]))

cbaxes = fig.add_subplot(gs[0])

# manually ensure that x- and y- axes are shared
ax[0].get_shared_x_axes().join(ax[1])
ax[0].get_shared_y_axes().join(ax[1])
# -----------------------------------------------

im0 = ax[0].imshow(harvest1, cmap='RdYlGn_r', vmin = 0.5, vmax = 1.65,
                   aspect="auto")

# We want to show all ticks...
ax[0].set_xticks(np.arange(len(vegetables)))
ax[0].set_yticks(np.arange(len(farmers0)))
# ... and label them with the respective list entries
ax[0].set_xticklabels(vegetables)
ax[0].set_yticklabels(farmers0)


# Rotate the tick labels and set their alignment.
plt.setp(ax[0].get_xticklabels(), rotation=45, ha="right",
         rotation_mode="anchor")



for i in range(len(farmers0)):
    for j in range(len(vegetables)):
        text = ax[0].text(j, i, harvest1[i, j],
                       ha="center", va="center", color="k")
    

im0 = ax[1].imshow(harvest2, cmap='RdYlGn_r', vmin = 0.5, vmax = 1.65,
                   aspect="auto")

# We want to show all ticks...
ax[1].set_xticks(np.arange(len(vegetables)))
ax[1].set_yticks(np.arange(len(farmers0)))
# ... and label them with the respective list entries
ax[1].set_xticklabels(vegetables)
ax[1].set_yticklabels(farmers0)


# Rotate the tick labels and set their alignment.
plt.setp(ax[1].get_xticklabels(), rotation=45, ha="right",
         rotation_mode="anchor")



for i in range(len(farmers0)):
    for j in range(len(vegetables)):
        text = ax[1].text(j, i, harvest2[i, j],
                       ha="center", va="center", color="k")
 

#cax = divider.append.axes("bottom", size= "5%", pad = 0.05)
bar2 = plt.colorbar(im0, cax = cbaxes , orientation = 'horizontal')

bar2.ax.set_title('90 % confidence interval of $d$')

fig.tight_layout()

plt.show()