'matplotlib share axis between a heatmap and home-made annotation axis
I am having major trouble to share correctly the x axis between a heatmap and a home-made annotation axis. I am using matplotlib2.2.2 (I upgrade from matplotlib 1.5 and sorely regret it).
Here is my default code and the resulting behavior:
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()
(I removed the colorbar part of the code to make it shorter)
I want to get ridd off the ugly white side bars. When I try to add the lines
x0, x1 = main_ax.get_xlim()
after creating the heatmap and
main_ax.set_xlim(x0, x1)
in the end, the upper bar gets too big:
Does anyone knows how I could correct this ?
Thanks !
Solution 1:[1]
This is happening because when you draw the rectangle with axvspan, it is adjusting the x axis of both subplots by adding margins. You can stop this happening by manually setting the x margin to 0 using ax.margins():
legend_ax.margins(x=0)
The full code:
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()
Gives something like:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | DavidG |

