1

Twiny() を使用せずにヒートマップしたい単一行のデータがあります。これは、アライメントの問題があるためです。私はこのサイトで多くのことを検索しましたが、これまでに到達したのは次のとおりです。

単一行のヒート マップを使用した imshow

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、上記の軸を入れることです。

前もって感謝します :)

4

4 に答える 4

4

twinyアスペクト比が設定されequalた軸は、同じ軸上に存在したくないようです。私にはバグのように思えますが、説明があるかもしれません。

そこで、2 つの軸を重ねてプロットすることで、この問題を回避しましょう。matplotlib2 つのサブプロットが同じ位置にある場合、はそれらを同じものと解釈するため、これは思ったほど簡単ではありません。しかし、使用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間違った位置が返されます。(これが失敗するまさにその理由かもしれません。)ax1equaltwiny

ここに画像の説明を入力


複数の行が必要な場合、解決策はそれほど変わりません。

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はバックエンドから によって実行されます。その結果、何らかの理由で画像が再描画された後、オーバーレイが再調整され、位置が変更された場合はシーンが再描画されます。

これは機能しますが、美しくありません。

于 2014-07-13T15:38:07.117 に答える
1

使用twin()してfrom mpl_toolkits.axes_grid1 import host_subplot

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import numpy as np

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()
ax1 = host_subplot(111, axes_class=AA.Axes)

ax2 = ax1.twin()
image = z

im = ax1.imshow(image, cmap=plt.cm.Blues, interpolation='nearest')
plt.colorbar(im)


ax1.set_xticks(np.arange(len(x)), minor=False)
ax2.set_xticks(np.arange(len(y)), minor=False)

#ax1.tick_params(labelbottom='on',labeltop='on', labelleft="off")
#ax2.tick_params(labelbottom='on',labeltop='on', labelleft="off")

ax1.set_yticklabels([])
ax2.set_yticklabels([])

ax1.tick_params(labelbottom='on',labeltop='on', labelleft="off")


plt.show()
于 2014-07-13T15:40:42.923 に答える
1

さて、軸の値を変更する代わりにテキストを使用することで、別の解決策を見つけました。

Twiny なしの単一の上下ラベルを imshow する

import numpy as np
import matplotlib.pyplot as plt

font = {'family' : 'sans-serif',
        'color'  : 'k',
        'weight' : 'normal',
        'size'   : 12,
        }

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()
#fig, ax1 = plt.subplots()

image = z

im = ax1.imshow(z, cmap=plt.cm.Blues, interpolation='nearest')
xticks = ax1.get_xticks()

top_lables_width_spacings = 0.83
top_lables_hight_spacings = -.53

for i in range(len(y)):
    ax1.text(xticks[i] + top_lables_width_spacings, top_lables_hight_spacings, y[i], fontdict=font)
#ax1.set_aspect('auto')

fig.colorbar(im, orientation='vertical')

ax1.set_xticks(np.arange(len(x)), minor=False)
ax1.set_xticklabels(x, minor=False)

ax1.tick_params(labelbottom='on',labeltop='off', labelleft="off")

ax1.set_title('$\eta$\n', size=17)      # represents the top axes label
plt.xlabel(r'$\theta$', size=17)                        # represents the bottom axes label
plt.show()
于 2014-07-13T13:52:51.513 に答える
0

これが正しければ、x を y に変更するだけでよいと思います。

ax1.set_xticklabels(y, minor=False)

これを行うと、プロットの上部と下部のリスト y にラベルが表示されます。

于 2014-07-13T13:45:38.933 に答える