matplotlib在热图和自制注释轴之间共享轴

时间:2018-04-16 14:26:45

标签: matplotlib axis heatmap

我在热图和自制注释轴之间正确分享x轴时遇到了很大的麻烦。我正在使用matplotlib2.2.2(我从matplotlib 1.5升级并且非常后悔)。

这是我的默认代码和结果行为:

mn = np.random.rand(2467, 2467)
list_coordinates = [0, 51, 220, 289, 605, 720, 776, 995, 1108, 1195, 1348, 1485, 1702, 1888, 2047, 2269,2467]
list_names = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', ]


# Prepare figure and axes
fig = plt.figure(figsize=(12, 14))
gs = gridspec.GridSpec(3, 1, hspace=0.05, wspace=0.1, height_ratios=[1, 12, 1])
main_ax = plt.subplot(gs[1])
legend_ax = plt.subplot(gs[0], sharex=main_ax)    

# Contact map
im = main_ax.imshow(mn**0.2, cmap='afmhot_r', vmin=0, vmax=0.9)

# Legend
colors = [name for name, hex in mcolors.cnames.items()]
for i, pos in enumerate(list_coordinates[:-1]):
    legend_ax.axvspan(list_coordinates[i], list_coordinates[i+1], 0, 0.1, color=colors[i])
    legend_ax.text((list_coordinates[i] + list_coordinates[i+1])/2, 0.2, list_names[i].replace('chr', ''), horizontalalignment='center', size='small')
legend_ax.set_axis_off()

# Show
plt.show()

image1 (我删除了代码的colorbar部分,使其更短)

我想摆脱丑陋的白边吧。当我尝试添加行

x0, x1 = main_ax.get_xlim()

创建热图后

main_ax.set_xlim(x0, x1)

最后,上方栏太大了:

image2

有谁知道我怎么能纠正这个?

谢谢!

1 个答案:

答案 0 :(得分:1)

这种情况正在发生,因为当您使用axvspan绘制矩形时,它会通过添加边距来调整两个子图的x轴。您可以使用ax.margins()

手动将x边距设置为0来阻止这种情况发生
legend_ax.margins(x=0)

完整代码:

mn = np.random.rand(2467, 2467)
list_coordinates = [0, 51, 220, 289, 605, 720, 776, 995, 1108, 1195, 1348, 1485, 1702, 1888, 2047, 2269,2467]
list_names = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', ]

# Prepare figure and axes
fig = plt.figure(figsize=(12, 14))
gs = gridspec.GridSpec(3, 1, hspace=0.05, wspace=0.1, height_ratios=[1, 12, 1])
main_ax = plt.subplot(gs[1])
legend_ax = plt.subplot(gs[0], sharex=main_ax)
legend_ax.margins(x=0) # manually set x margin to 0

# Contact map
im = main_ax.imshow(mn**0.2, cmap='afmhot_r', vmin=0, vmax=0.9)

# Legend
colors = [name for name, hex in mcolors.cnames.items()]
for i, pos in enumerate(list_coordinates[:-1]):
    legend_ax.axvspan(list_coordinates[i], list_coordinates[i+1], 0, 0.1, color=colors[i])
    legend_ax.text((list_coordinates[i] + list_coordinates[i+1])/2, 0.2, list_names[i].replace('chr', ''), horizontalalignment='center', size='small')
legend_ax.set_axis_off()

# Show
plt.show()

给出类似的东西:

enter image description here