Skip to main content
 首页 » 编程设计

python之没有 twiny 的 imshow 顶轴标签

2025年05月04日15duanxz

我有一行数据,我想在不使用 twiny() 的情况下对其进行热映射,因为它会出现对齐问题。 我在这个网站上搜索了很多,这就是我到目前为止所达到的:

import numpy as np 
import matplotlib.pyplot as plt 
 
x = "0.2, 0.3, 0.4, 0.5, 0.6".split(",") 
y = "180, 175, 170, 169, 150".split(",") 
z = [[5000, 4800, 4500, 4450, 4300]] 
 
fig, ax1 = plt.subplots() 
 
image = z 
 
im = ax1.imshow(image, cmap=plt.cm.Blues, interpolation='nearest') 
plt.colorbar(im) 
 
 
ax1.set_xticks(np.arange(len(x)), minor=False) 
 
ax1.set_xticklabels(x, minor=False) 
#ax1.set_yticklabels(y, minor=False) 
 
ax1.tick_params(labelbottom='on',labeltop='on', labelleft="off") 
 
 
 
plt.show() 

如您所见,上轴的文本与下轴的文本完全相同。 我想要的是将 y 放在上面的轴上。

提前致谢:)

请您参考如下方法:

似乎twiny和纵横比设置为 equal 的轴不想生活在同一个轴上。对我来说,这似乎是一个错误,但可能会有一个解释。

因此,让我们通过在彼此之上绘制两个轴来解决这个问题。这并不像听起来那么微不足道,因为如果两个子图位于同一位置,matplotlib将它们解释为同一个。但是,使用 add_plot不存在这样的问题。

import numpy as np 
import matplotlib.pyplot as plt 
 
x = "0.2, 0.3, 0.4, 0.5, 0.6".split(",") 
y = "180, 175, 170, 169, 150".split(",") 
z = [[5000, 4800, 4500, 4450, 4300]] 
 
fig = plt.figure() 
ax1 = fig.add_subplot(111) 
 
image = z 
 
im = ax1.imshow(image, cmap=plt.cm.Blues, interpolation='nearest') 
plt.colorbar(im) 
 
ax1.set_xticks(np.arange(len(x)), minor=False) 
ax1.set_xticklabels(x, minor=False) 
ax1.tick_params(labelbottom='on',labeltop='off', labelleft="off",  
    top='off', left='off', right='off') 
 
# create another axes on the same position: 
# - create second axes on top of the first one without background 
# - make the background invisible 
# - set the x scale according to that of `ax1` 
# - set the top ticks on and everything else off 
# - set the size according to the size of `ax1` 
ax2 = fig.add_axes(ax1.get_position(), frameon=False) 
ax2.tick_params(labelbottom='off',labeltop='on', labelleft="off", labelright='off', 
    bottom='off', left='off', right='off') 
ax2.set_xlim(ax1.get_xlim()) 
ax2.set_xticks(np.arange(len(y))) 
ax2.set_xticklabels(y, minor=False) 
 
plt.draw() 
ax2.set_position(ax1.get_position()) 
 
plt.draw() 
plt.show() 

plt.draw()在 set_position 之前需要否则 get_position将为 ax1 返回错误的位置由于使用 equal方面。 (这可能就是 twiny 失败的原因。)


如果你需要有多行,解决方案没有什么不同:

import numpy as np 
import matplotlib.pyplot as plt 
 
x = "0.2, 0.3, 0.4, 0.5, 0.6".split(",") 
y = "180, 175, 170, 169, 150".split(",") 
z = [[5000, 4800, 4500, 4450, 4300]] 
 
numRows = 8 
 
fig, subaxes = plt.subplots(nrows=numRows, ncols=1) 
axeslist = subaxes.flatten() 
 
for ax in axeslist: 
    im = ax.imshow(z, cmap=plt.cm.Blues, interpolation='nearest') 
 
    ax.tick_params(labelbottom='off',labeltop='off', labelleft="off", labelright='off', 
                   bottom='off', top='off', left='off', right='off') 
    if ax == axeslist[0]: 
        ax.set_title('Avg. (s)\n', size=13) 
    elif ax == axeslist[-1]: 
        ax.tick_params(bottom='on', labelbottom='on') 
        ax.set_xticks(range(len(x))) 
        ax.set_xticklabels(x) 
 
# reserve some space between the subplots 
fig.subplots_adjust(hspace=0.07*(numRows-1)) 
 
# create the overlay images, add them as extra properties of the original images 
for ax in axeslist: 
    axnew = fig.add_axes(ax.get_position(), frameon=False) 
    axnew.tick_params(labelbottom='off',labeltop='on', labelleft="off", labelright='off', 
                   bottom='off', top='on', left='off', right='off') 
    axnew.set_xlim(ax.get_xlim()) 
    axnew.set_xticks(range(len(y))) 
    axnew.set_xticklabels(y) 
    ax.extra_axes = axnew 
 
# update the secondary axes positions 
# draw() only if there was something changed (important!) 
def update_secondary(event=None): 
    position_changed = False 
    for ax in axeslist: 
        if ax.extra_axes.get_position().bounds == ax.get_position().bounds: 
            continue 
        position_changed = True 
        ax.extra_axes.set_position(ax.get_position()) 
 
    if position_changed: 
        plt.draw() 
 
# register the secondary axes updater as a callback 
fig.canvas.mpl_connect('draw_event', update_secondary) 
 
# make sure everything is drawn 
plt.draw()     

由于覆盖更新必须在绘制完所有其他内容后执行,因此此处由 draw_event 完成从后端。结果是由于某种原因重新绘制图像后,重新调整叠加层,如果任何位置发生变化,都会重新绘制场景。

这可行但不漂亮。