この記事でグラフの領域をグラデーションにする方法を調べたのですが、その応用としてUV-Visスペクトルを波長に応じた色で塗りつぶしたくなった。
波長をRGBに変換する方法を調べたらこちらに欲しいコードがあったので拝借しました。
Coding Mess: Conversion of wavelength in nanometers to RGB in Python
xが380-780nmの時にRGBに変換して塗りつぶして、それ以外の範囲は黒色になります。実際に使うときはxとy1をスペクトルのデータに変換するといい感じになるかと。
import matplotlib.pyplot as plt import numpy as np #波長をRGBに変換するコード #波長(380~780nm)を[R,G,B]にして返す。380~780nmから外れた場合は黒[255,255,255]を返す #参考:https://codingmess.blogspot.com/2009/05/conversion-of-wavelength-in-nanometers.html def wav2RGB(wavelength): w = int(wavelength) # colour if w >= 380 and w < 440: R = -(w - 440.) / (440. - 350.) G = 0.0 B = 1.0 elif w >= 440 and w < 490: R = 0.0 G = (w - 440.) / (490. - 440.) B = 1.0 elif w >= 490 and w < 510: R = 0.0 G = 1.0 B = -(w - 510.) / (510. - 490.) elif w >= 510 and w < 580: R = (w - 510.) / (580. - 510.) G = 1.0 B = 0.0 elif w >= 580 and w < 645: R = 1.0 G = -(w - 645.) / (645. - 580.) B = 0.0 elif w >= 645 and w <= 780: R = 1.0 G = 0.0 B = 0.0 else: R = 0.0 G = 0.0 B = 0.0 # intensity correction if w >= 380 and w < 420: SSS = 0.3 + 0.7*(w - 350) / (420 - 350) elif w >= 420 and w <= 700: SSS = 1.0 elif w > 700 and w <= 780: SSS = 0.3 + 0.7*(780 - w) / (780 - 700) else: SSS = 0.0 SSS *= 255 return [int(SSS*R), int(SSS*G), int(SSS*B)] ##グラフの作成 fig, ax = plt.subplots() #x,yの定義 #本来はここにスペクトルに対応するx,yを入れる x = np.linspace(380, 780, 1000) y1 = np.sin((x-200)/150)+1 #y1:sin関数 y2 = np.zeros_like(x) #y2:0 #y1,y2,y3の線をプロット ax.plot(x, y1, color='black') ax.plot(x, y2, color='black') #for文で塗りつぶす for i in range(len(x) - 1): color = wav2RGB(x[i])#波長をRGBに変換 ax.fill_between(x[i:i+2],#塗りつぶしを行うxの範囲 y1[i:i+2],#yの塗りつぶしの片側1 y2[i:i+2], #yの塗りつぶしの片側2 color=(color[0]/255, color[1]/255, color[2]/255, 0.5), #(R,G,B,透明度) lw=0.5) plt.show()
参考サイト
Coding Mess: Conversion of wavelength in nanometers to RGB in Python