matplotlibのカラーマップを自分で作成する時に起こった問題。
pythonで画像を表示する。
pythonで画像を表示するとき、自分は、matplotlibかpqtgraphを使う。(ほかにもいろいろ方法はある)
両方とも、数値をプロットしたりするときに使うソフト。
詳しい使い方は、ここにある。使う度に毎回参照している。多分一生覚えられない。
例えば、以下のようなコードを実行したとき、
ファイルダイアログが開いて、任意のファイルを開き、画像を表示する。
# coding: Shift_JIS
import matplotlib.pyplot as plt
# 画像表示用の関数1
import matplotlib.image as mpimg
# 画像表示用の関数2
import tkinter.filedialog as tkfd
# ファイルダイアログ用の関数。
f, (ax1) = plt.subplots(1)
# 作図
filename = tkfd.askopenfilename()
#ファイルダイアログを出し、選んだファイルを変数に代入
img1 = mpimg.imread(filename)
#画像
ax1.imshow(img1)
plt.show()
これを、RGB別に分けて表示するには、直感的にはRGBの情報が入った配列(np.array)をこうやってとりだしたい。
img[:,:,0]
上記を使って、下記のようなコードを実行すると、
import numpy as np
# 数値計算ライブラリ
import matplotlib.pyplot as plt
# 画像表示用の関数1
import matplotlib.image as mpimg
# 画像表示用の関数2
import tkinter.filedialog as tkfd
# ファイルダイアログ用の関数。
f, ((ax11,ax12,ax13,), (ax21,ax22,ax23,)) = plt.subplots(2,3)
# 作図
ax11.axis("off")
ax13.axis("off")
filename = tkfd.askopenfilename()
#ファイルダイアログを出し、選んだファイルを変数に代入
img1 = mpimg.imread(filename)
ax12.imshow(img1)
ax21.imshow(img1[:,:,0])
ax22.imshow(img1[:,:,1])
ax23.imshow(img1[:,:,2])
plt.show()
こんな感じになる。
色が付いている。
これは、カラーマップが、良くない。カラーマップがjetというやつだから、こうなった。
cmapとは
前の例を、カラーマップを指定すると、こんな感じにできる。
import numpy as np
# 数値計算ライブラリ
import matplotlib.pyplot as plt
# 画像表示用の関数1
import matplotlib.image as mpimg
# 画像表示用の関数2
import tkinter.filedialog as tkfd
# ファイルダイアログ用の関数。
f, ((ax11,ax12,ax13,), (ax21,ax22,ax23,)) = plt.subplots(2,3)
# 作図
ax11.axis("off")
ax13.axis("off")
filename = tkfd.askopenfilename()
#ファイルダイアログを出し、選んだファイルを変数に代入
img1 = mpimg.imread(filename)
#画像
ax12.imshow(img1)
ax21.imshow(img1[:,:,0], cmap="hot")
ax22.imshow(img1[:,:,1], cmap="summer")
ax23.imshow(img1[:,:,2], cmap="winter")
ax21.set_title("hot")
ax22.set_title("summer")
ax23.set_title("winter")
plt.show()
下側の、図の、タイトルが、cmap。
ぱっと見は、これで完成しているように見えるが…
これじゃない。こうじゃないんだよ!
まず
- 色が濃いはずの部分が、薄くなっている!!
- 色が赤青緑ではない!!!!!!!!!!!
白→赤ないし、黒→赤みたいになってないとダメ。できあいのカラーマップじゃダメ。
なので、任意の二色のグラデーションを作りたい。
matplotlibでの解決方法
公式ではcmapの作り方はここら辺を参考にできる
が、cdictの中身の意味はここを見る必要があるし、公式よりもここの方が参考になるかもしれない。
import matplotlibimport numpy as np
# 数値計算ライブラリ
import matplotlib.pyplot as plt
# 画像表示用の関数1
import matplotlib.image as mpimg
# 画像表示用の関数2
import tkinter.filedialog as tkfd
# ファイルダイアログ用の関数。
cdict = {'red': ((0.0, 0.0, 0.0),(1.0, 1.0, 1.0)),
'green': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0)),
'blue': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0))
}
cmap_RtoBRK = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict,256)
cdict2 = {'red': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0)),
'green': ((0.0, 0.0, 0.0),(1.0, 1.0, 1.0)),
'blue': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0))
}
cmap_GtoBRK = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict2,256)
cdict3 = {'red': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0)),
'green': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0)),
'blue': ((0.0, 0.0, 0.0),(1.0, 1.0, 1.0))
}
cmap_BtoBRK = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict3,256)
f, ((ax11,ax12,ax13,), (ax21,ax22,ax23,)) = plt.subplots(2,3)
# 作図
ax11.axis("off")
ax13.axis("off")
filename = tkfd.askopenfilename()
#ファイルダイアログを出し、選んだファイルを変数に代入
img1 = mpimg.imread(filename)#画像
ax12.imshow(img1)
ax21.imshow(img1[:,:,0], cmap=cmap_RtoBRK)
ax22.imshow(img1[:,:,1], cmap=cmap_GtoBRK)
ax23.imshow(img1[:,:,2], cmap=cmap_BtoBRK)
plt.show()
黒なんか指定した覚えはない。
白い紙に、絵の具を置くと、こうなるでしょ!?
という人は、こっちがいいかも…
import matplotlibimport numpy as np
# 数値計算ライブラリ
import matplotlib.pyplot as plt
# 画像表示用の関数1
import matplotlib.image as mpimg
# 画像表示用の関数2
import tkinter.filedialog as tkfd
# ファイルダイアログ用の関数。
cdict = {'red': ((0.0, 1.0, 1.0),(1.0, 1.0, 1.0)),
'green': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0)),
'blue': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0))
}
cmap_RtoBRK = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict,256)
cdict2 = {'red': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0)),
'green': ((0.0, 1.0, 1.0),(1.0, 1.0, 1.0)),
'blue': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0))
}
cmap_GtoBRK = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict2,256)
cdict3 = {'red': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0)),
'green': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0)),
'blue': ((0.0, 1.0, 1.0),(1.0, 1.0, 1.0))
}
cmap_BtoBRK = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict3,256)
f, ((ax11,ax12,ax13,), (ax21,ax22,ax23,)) = plt.subplots(2,3)
# 作図
ax11.axis("off")
ax13.axis("off")
filename = tkfd.askopenfilename()
#ファイルダイアログを出し、選んだファイルを変数に代入
img1 = mpimg.imread(filename)
#画像
ax12.imshow(img1)
ax21.imshow(img1[:,:,0], cmap=cmap_RtoBRK)
ax22.imshow(img1[:,:,1], cmap=cmap_GtoBRK)
ax23.imshow(img1[:,:,2], cmap=cmap_BtoBRK)
plt.show()
どちらが正しいのか
黒→赤とかが、本来の表現だが…
なぜならば、PCやら、携帯やらをonしていない時、そのディスプレイは、大抵黒。
off時に、黒以外の色になるディスプレイなんて、ブラウン管TVが灰色だったり、GBAとかワンダースワン以来、お目にかかっていない。
ここに、3色のLEDとか液晶とか何かが光って、画面を表示している。
3色全部つくと、白くなる。この光の強さと、値の大きさを対応させているから、黒→色が正しい表現。
しかし、学校とかでは、絵を描く時に、白い紙を配られて、そこに色を置いた。つまり、何もないところは白で、色があるところは赤。
この考え方で行くと、白い紙の上では、白→色が正しい表現になる。
紙と、ディスプレイで、表現の方法が違う。
紙の場合は、光っていない。
ディスプレイの場合は光っている。
この差は大きい。
ただ、PCはディスプレイで見るとはいえ、紙的な表現を心掛けた方がいいと思っている。
なぜならば、印刷時のインク消費量が上がるから。
import matplotlibimport numpy as np
# 数値計算ライブラリ
import matplotlib.pyplot as plt
# 画像表示用の関数1
import matplotlib.image as mpimg
# 画像表示用の関数2
import tkinter.filedialog as tkfd
# ファイルダイアログ用の関数。
cdict = {'red': ((0.0, 1.0, 1.0),(1.0, 1.0, 1.0)),
'green': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0)),
'blue': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0))
}
cmap_RtoBRK = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict,256)
cdict2 = {'red': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0)),
'green': ((0.0, 1.0, 1.0),(1.0, 1.0, 1.0)),
'blue': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0))
}
cmap_GtoBRK = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict2,256)
cdict3 = {'red': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0)),
'green': ((0.0, 1.0, 1.0),(1.0, 0.0, 0.0)),
'blue': ((0.0, 1.0, 1.0),(1.0, 1.0, 1.0))
}
cmap_BtoBRK = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict3,256)
cdict12 = {'red': ((0.0, 0.0, 0.0),(1.0, 1.0, 1.0)),
'green': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0)),
'blue': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0))
}
cmap_RtoBRK2 = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict12,256)
cdict22 = {'red': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0)),
'green': ((0.0, 0.0, 0.0),(1.0, 1.0, 1.0)),
'blue': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0))
}
cmap_GtoBRK2 = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict22,256)
cdict32 = {'red': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0)),
'green': ((0.0, 0.0, 0.0),(1.0, 0.0, 0.0)),
'blue': ((0.0, 0.0, 0.0),(1.0, 1.0, 1.0))
}
cmap_BtoBRK2 = matplotlib.colors.LinearSegmentedColormap('my_colormap',cdict32,256)
f, ((ax11,ax12,ax13), (ax21,ax22,ax23), (ax31,ax32,ax33)) = plt.subplots(3,3)
# 作図
ax11.axis("off")
ax13.axis("off")
filename = tkfd.askopenfilename()
#ファイルダイアログを出し、選んだファイルを変数に代入
img1 = mpimg.imread(filename)
#画像
ax12.imshow(img1)
ax21.imshow(img1[:,:,0], cmap=cmap_RtoBRK)
ax22.imshow(img1[:,:,1], cmap=cmap_GtoBRK)
ax23.imshow(img1[:,:,2], cmap=cmap_BtoBRK)
ax31.imshow(img1[:,:,0], cmap=cmap_RtoBRK2)
ax32.imshow(img1[:,:,1], cmap=cmap_GtoBRK2)
ax33.imshow(img1[:,:,2], cmap=cmap_BtoBRK2)
plt.show()
- 中速フーリエ変換 ~離散フーリエ変換より..
- 断面二次モーメントを、座標点の配列から計..
- 断面二次モーメントを、座標点の配列から計..
- fontファイルの文字データ(グリフ)を..
- matplotlibのpyplot.pl..
- 計算力学技術者試験の問題集 自炊(裁断→..
- pythonで、ホワイトノイズやピンクノ..
- 脳ドッグに行ってきた。→MRIの画像デー..
- matplotlibのimshowで円を..
- matplotlibの、cmapを、徐々..
- matplotlibのmake_axes..
- matplotlib floatinga..
- matplotlib plotの色を、値..
- Pythonで、「二次元フーリエ変換した..
- matplotlibのlinestyle..
- matplotlibのannotateの..
- matplotlibで、x軸とy軸の数字..
- VBAで、pythonのrangeとか、..
- matplotlibのaxes3Dで、a..
- matplotlibのlatexで、行列..