【问题标题】:Trimming a color bar after normalize in matplotlib在matplotlib中标准化后修剪颜色条
【发布时间】:2021-06-24 16:16:52
【问题描述】:

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

如下图所示,沿x轴有一个空白区域。

所以我想将 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()

【问题讨论】:

  • 您正在设置fig.add_axes([0.10,0.10,1.2,2]),这远远超出了 x 和 y 的可用 0,1 区域。为什么?
  • 四个数字到底是什么意思?我注意到你在下面的代码中写了 x0, y0, width, height,我特别不明白 x0 和 y0 的含义。谢谢!
  • x0,y0 是左下角。一切都以figure coordinates 衡量,从周围图左下角的 0,0 到右上角的 1,1。
  • 再次感谢约翰!你很有帮助。祝您在 2021 年过得愉快!

标签: python matplotlib plot boxplot colorbar


【解决方案1】:

将颜色条与主轴完全对齐的最简单方法是将其轴创建为cax = fig.add_axes([...]),使用与主轴相同的 x 和宽度并调整 y 和高度。然后颜色条可以创建为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)

【讨论】:

  • 成功了!非常感谢您的解释,虽然我不完全理解!但我知道如何调整你的脚本。再次感谢!!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-25
  • 2012-07-22
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 2015-02-05
  • 2017-07-15
相关资源
最近更新 更多