twiny
アスペクト比が設定されequal
た軸は、同じ軸上に存在したくないようです。私にはバグのように思えますが、説明があるかもしれません。
そこで、2 つの軸を重ねてプロットすることで、この問題を回避しましょう。matplotlib
2 つのサブプロットが同じ位置にある場合、はそれらを同じものと解釈するため、これは思ったほど簡単ではありません。しかし、使用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
はバックエンドから によって実行されます。その結果、何らかの理由で画像が再描画された後、オーバーレイが再調整され、位置が変更された場合はシーンが再描画されます。
これは機能しますが、美しくありません。