web-dev-qa-db-ja.com

matplotlibのimshow()に凡例を追加する方法

matplotlibを使用しています

plot()またはbar()では、ラベルを追加すれば、簡単に凡例を付けることができます。しかし、それがcontourf()またはimshow()の場合はどうでしょうか。

色の範囲を表示できるcolorbar()があることは知っていますが、満足できません。名前(ラベル)のある伝説が欲しいです。

enter image description here

私が考えることができるのは、行列の各要素にラベルを追加してから、legend()を試して、それが機能するかどうかを確認することですが、値のように要素にラベルを追加するにはどうすればよいですか?

私の場合、生データは次のようになります。

1,2,3,3,4
2,3,4,4,5
1,1,1,2,2

たとえば、1は「草」、2は「砂」、3は「丘」などを表します。 imshow()は私の場合と完全に連携しますが、凡例はありません。

私の質問は:

  1. 凡例を自動的に追加できる関数はありますか?たとえば、私の場合は、次のようにする必要があります:someFunction( 'grass'、 'sand'、...)

  2. ない場合は、マトリックスの各値にラベルを追加するにはどうすればよいですか。たとえば、マトリックス「grass」のすべての1にラベルを付け、マトリックス「sand」のすべての2にラベルを付けます...など。

ありがとうございました!

編集

@dnalowのおかげで、本当にスマートです。しかし、私はまだ正式な解決策があるかどうか疑問に思います。

7
rankthefirst

凡例を作成するための行が必要なため、凡例を偽造する必要があると思います。

あなたはこのようなことをすることができます:

import pylab as pl
mycmap = pl.cm.jet # for example
for entry in pl.unique(raw_data):
    mycolor = mycmap(entry*255/(max(raw_data) - min(raw_data)))
    pl.plot(0, 0, "-", c=mycolor, label=mynames[entry])

pl.imshow(raw_data)
pl.legend()

原因として、これはまだあまり満足のいくものではありません。しかし、多分あなたはその上に何かを構築することができます。

[編集:欠落している括弧を追加]

3
dnalow

誰かがまだ興味を持っている場合に備えて、ここで 同様の質問 の解決策を引用します:

マトリックス内のすべての値の凡例を配置することは、それらの数が多すぎない場合にのみ意味があると思います。したがって、マトリックスに8つの異なる値があると仮定します。次に、それぞれの色のプロキシアーティストを作成し、このような凡例に入れることができます。

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np

# create some data
data = np.random.randint(0, 8, (5,5))
# get the unique values from data
# i.e. a sorted list of all values in data
values = np.unique(data.ravel())

plt.figure(figsize=(8,4))
im = plt.imshow(data, interpolation='none')

# get the colors of the values, according to the 
# colormap used by imshow
colors = [ im.cmap(im.norm(value)) for value in values]
# create a patch (proxy artist) for every color 
patches = [ mpatches.Patch(color=colors[i], label="Level {l}".format(l=values[i]) ) for i in range(len(values)) ]
# put those patched as legend-handles into the legend
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0. )

plt.grid(True)
plt.show()

enter image description here

matplotlib.pylab.textを使用して、プロットにテキストを追加し、凡例のようにカスタマイズすることができます

例えば:

import numpy as np
import matplotlib.cm as cm
import matplotlib.pylab as plt

raw_data = np.random.random((100, 100))
fig, ax = plt.subplots(1)
ax.imshow(raw_data, interpolation='nearest', cmap=cm.gray)
ax.text(5, 5, 'your legend', bbox={'facecolor': 'white', 'pad': 10})
plt.show()

次のようになります random noise

詳細については、テキストに関するmatplotlibのドキュメントを確認してください matplotlibテキストの例

6
mark jay

私はあなたの問題のような土地利用地図を描くために同じプロジェクトに取り組んでいます。上記の答えに従った私の解決策は次のとおりです。

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np
##arrayLucc is the array of land use types 
arrayLucc = np.random.randint(1,4,(5,5))
## first you need to define your color map and value name as a dic
t = 1 ## alpha value
cmap = {1:[0.1,0.1,1.0,t],2:[1.0,0.1,0.1,t],3:[1.0,0.5,0.1,t]}
labels = {1:'agricultural land',2:'forest land',3:'grassland'}
arrayShow = np.array([[cmap[i] for i in j] for j in arrayLucc])    
## create patches as legend
patches =[mpatches.Patch(color=cmap[i],label=labels[i]) for i in cmap]

plt.imshow(arrayShow)
plt.legend(handles=patches, loc=4, borderaxespad=0.)
plt.show()

result show below

この解像度はあまり良くないようですが、機能します。他の方法も探しています。

1
Jingtao Yao