我有一行数据要在不使用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完成。结果是,由于某种原因重新绘制了图像后,将重新调整叠加层,并且如果更改了任何位置,则将重新绘制场景。

这有效,但并不美观。

09-26 04:07