【matplotlib】波長に応じて色を変えたグラデーションで塗りつぶしたい【python】

 

この記事でグラフの領域をグラデーションにする方法を調べたのですが、その応用としてUV-Visスペクトルを波長に応じた色で塗りつぶしたくなった。

chemstat.hatenablog.com

波長を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