毎日、pythonと格闘しているumesakuです。「pythonで始める機械学習」のP.144に謎の一文があったのでちょっと掘り下げてみました。
###画像を愚直にプロットする
from sklearn.datasets import fetch_lfw_people
import matplotlib.pyplot as plt
%matplotlib inline
#jupyter notebookで動かす時はこの呪文が必要になります。
people = fetch_lfw_people(min_faces_per_person=20, resize=0.7)
# 先に名前のリストをとっておく
names = []
for t in people.target:
names.append(people.target_names[t])
# 名前を短くしたいので写真は別の変数名にする
images = people.images
# テキストでは2行5列。ちょっと楽をして2行3列に写真を並べた。
fix, axis = plt.subplots(2, 3, figsize=(15, 8), subplot_kw={'xticks':[], 'yticks':[]})
# サブプロットの画像表示メソッドがimshow
# サブプロットのタイトルに名前表示。setを忘れずに
axis[0, 0].imshow(images[0])
axis[0, 0].set_title(names[0])
axis[0, 1].imshow(images[1])
axis[0, 1].set_title(names[1])
axis[0, 2].imshow(images[2])
axis[0, 2].set_title(names[2])
axis[1, 0].imshow(images[3])
axis[1, 0].set_title(names[3])
axis[1, 1].imshow(images[4])
axis[1, 1].set_title(names[4])
axis[1, 2].imshow(images[5])
axis[1, 2].set_title(names[5])
plt.show()
上記のコードでは一つずつに対して写真と名前をセットしているが、サブプロットの数が増えてくると、どんどんどんどん大変。100枚とか、もー無理(汗)。
ループで効率よく処理したいんだけど、axis が 2 次元配列で、names/images が 1 次元配列だから単純なループにしたらエラーになっちゃう。私では到底処理できない(いやいや簡単にできるよという方、ぜひ教えてください!)
だから、axisをaxis.revel()で一次元配列にする。
そうすれば、names/images/axis が一つのループで書けるようになる。
###テキスト通り書いてみた
P.144です。ちょっとaxis1 = axis.ravel()でアレンジしています。
fix, axis = plt.subplots(2, 3, figsize=(15, 8), subplot_kw={'xticks':[], 'yticks':[]})
#axisを1 次元配列にする
axis1 = axis.ravel()
# これで一つのループで書ける
for name, image, ax in zip(names, images, axis1):
ax.imshow(image,cmap='Greys_r')
ax.set_title(name)
plt.show()
###アウトプット
どちらもアウトプットは同じです。なぜか黄緑色になっちゃいますけど(涙
axes.revelは覚えておこう!
※以前axesとaxisは違うとご指摘頂きました。調べても良く理解できませんでした。なので、今回両方試行したのですがどちらも同じ結果になりました。また、見て頂けてご指摘頂けたら嬉しいです!
追、@skotaroさんのアドバイスで、ax.imshow(image, cmap='Greys_r')とすると白黒写真のようになりました!cmapとはカラーマップ、_rはreverseの略で'Grey'だけだと白黒写真の反転バージョン、ということのようです!