在 matplotlib 中归一化后修剪颜色条

Trimming a color bar after normalize in matplotlib

我已将颜色条与水平箱形图的 x 轴对齐。

正如您在底部的图中看到的,沿 x 轴有一个空白区域。

所以我想 trim x 轴连同颜色条,它由 vminvmax

归一化

知道如何实现吗?

非常感谢!

test_data = [np.random.normal(mean, 1, 10) for mean in range(400, 500, 10)]

### set sns style
sns.set_style('white')

### set fig, ax
fig = plt.figure(figsize=(4,2))
ax1 = fig.add_axes([0.10,0.10,1.2,2])

### Define color bar
# choose color map
cmap = plt.get_cmap('nipy_spectral')
# normalize min and max
norm = mpl.colors.Normalize(vmin=380,vmax=780)
# assign cmap and norm
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])

### Plot color bar (change "pad" to adjust distance of color bar to x-axis)
plt.colorbar(sm, ticks=np.linspace(380,780,11), location="bottom", pad=0)

### Plot boxplot
bplot = ax1.boxplot(test_data, vert=False, patch_artist=True)

### Set axis
ax1.set_yticklabels(["a","b","c","d","e","f","g","h","i","j"])
ax1.get_xaxis().set_visible(False)
ax1.set_xlim(380,780)   

plt.show()

将颜色条与主坐标轴完全对齐的最简单方法是,使用与主坐标轴相同的 x 和宽度并调整 y 和高度,将其坐标轴也创建为 cax = fig.add_axes([...])。然后可以将颜色条创建为 plt.colorbar(sm, ticks=np.linspace(380, 780, 11), orientation='horizontal', cax=cax).

由于您想要减少部分颜色条,通过 imshow() 使用范围将其与 x 轴对齐可能更容易绘制。

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import matplotlib as mpl

test_data = [np.random.normal(mean, 1, 10) for mean in range(400, 500, 10)]

sns.set_style('white')

fig = plt.figure(figsize=(10, 3))
ax1 = fig.add_axes([0.10, 0.17, 0.88, 0.80])  # x0, y0, width, height in figure coordinates
cax = fig.add_axes([0.10, 0.12, 0.88, 0.05], sharex=ax1)  # use same x0 and width

### Define color bar
cmap = plt.get_cmap('nipy_spectral')
norm = mpl.colors.Normalize(vmin=380, vmax=780)
xmin, xmax = 380, 500
cax.imshow(np.linspace(xmin, xmax, 100).reshape(1, -1), extent=[xmin, xmax, 0, 1], cmap=cmap, norm=norm, aspect='auto')
cax.set_yticks([])

bplot = ax1.boxplot(test_data, vert=False, patch_artist=True)

ax1.set_yticklabels(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"])
ax1.set_xlim(xmin, xmax)
ax1.tick_params(axis='x', labelbottom=False)
cax.set_xticks(np.arange(xmin, xmax + 1, 20))

plt.show()

imshow() 也可用于以类似方式为箱线图矩形着色。下面的示例使用经过改编的示例数据来更好地说明这个概念。注意imshow重置了xlims和ylims,所以需要先保存然后再重置。

test_data = [np.random.uniform(mean - 20, mean + 20, 10) for mean in range(400, 500, 10)]

sns.set_style('white')

fig = plt.figure(figsize=(10, 3))
ax1 = fig.add_axes([0.10, 0.17, 0.88, 0.80])  # x0, y0, width, height in figure coordinates
cax = fig.add_axes([0.10, 0.12, 0.88, 0.05], sharex=ax1)  # use same x0 and width

### Define color bar
cmap = plt.get_cmap('nipy_spectral')
norm = mpl.colors.Normalize(vmin=380, vmax=780)
xmin, xmax = 380, 510
cax.imshow(np.linspace(xmin, xmax, 200).reshape(1, -1), extent=[xmin, xmax, 0, 1], cmap=cmap, norm=norm, aspect='auto')
cax.set_yticks([])

bplot = ax1.boxplot(test_data, vert=False, patch_artist=True, medianprops={'color': 'white'})

ax1.set_yticklabels(["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"])
ax1.tick_params(axis='x', labelbottom=False)
cax.set_xticks(np.arange(xmin, xmax + 1, 20))
ymin, ymax = ax1.get_ylim()

for art in ax1.artists:
    art.set_facecolor('none')  # make transparent
    x0, y0, x1, y1 = art.get_path().get_extents().extents
    ax1.imshow(np.linspace(x0, x1, 100).reshape(1, -1), extent=[x0, x1, y0, y1],
               cmap=cmap, norm=norm, aspect='auto', zorder=0)
ax1.set_xlim(xmin, xmax)
ax1.set_ylim(ymin, ymax)