如何用光谱颜色填充 x 轴和曲线之间的 space?

How can I fill the space between the x-axis and the curve with the spectral colors?

如何用相应的颜色填充x轴和光谱曲线之间的space? 它只显示底部带中的颜色。 It would be great if the plot looks like the example: https://www.google.com/search?q=ocean+view+software&client=firefox-b-d&sxsrf=ALeKk00ddh8swDsz_7aKabw4-l1CXv3yEA:1593189268241&source=lnms&tbm=isch&sa=X&ved=2ahUKEwjByJLD9J_qAhUGwKQKHf7iBY4Q_AUoAXoECAwQAw&biw=1366&bih=654#imgrc=I3KeJE0Rq3taPM

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
import pandas as pd

def wavelength_to_rgb(wavelength, gamma=0.8):
    wavelength = float(wavelength)
    if wavelength >= 380 and wavelength <= 750:
        A = 1.
    else:
        A=0.5
    if wavelength < 380:
        wavelength = 380.
    if wavelength >750:
        wavelength = 750.
    if wavelength >= 380 and wavelength <= 440:
        attenuation = 0.3 + 0.7 * (wavelength - 380) / (440 - 380)
        R = ((-(wavelength - 440) / (440 - 380)) * attenuation) ** gamma
        G = 0.0
        B = (1.0 * attenuation) ** gamma
    elif wavelength >= 440 and wavelength <= 490:
        R = 0.0
        G = ((wavelength - 440) / (490 - 440)) ** gamma
        B = 1.0
    elif wavelength >= 490 and wavelength <= 510:
        R = 0.0
        G = 1.0
        B = (-(wavelength - 510) / (510 - 490)) ** gamma
    elif wavelength >= 510 and wavelength <= 580:
        R = ((wavelength - 510) / (580 - 510)) ** gamma
        G = 1.0
        B = 0.0
    elif wavelength >= 580 and wavelength <= 645:
        R = 1.0
        G = (-(wavelength - 645) / (645 - 580)) ** gamma
        B = 0.0
    elif wavelength >= 645 and wavelength <= 750:
        attenuation = 0.3 + 0.7 * (750 - wavelength) / (750 - 645)
        R = (1.0 * attenuation) ** gamma
        G = 0.0
        B = 0.0
    else:
        R = 0.0
        G = 0.0
        B = 0.0
    return (R,G,B,A)

clim=(350,780)
norm = plt.Normalize(*clim)
wl = np.arange(clim[0],clim[1]+1,2)
colorlist = list(zip(norm(wl),[wavelength_to_rgb(w) for w in wl]))
spectralmap = matplotlib.colors.LinearSegmentedColormap.from_list("spectrum", colorlist)

fig, axs = plt.subplots(1, 1, figsize=(6,6), tight_layout=True)

# set directory
df = pd.read_excel('Reflexionsspektren.xlsx', 'Tabelle1')
# data for plot1
wavelengths = df['Wavelength']
spectrum = df['Fresh']

plt.plot(wavelengths, spectrum, color='darkred')

y = np.linspace(0, 6, 100)
X,Y = np.meshgrid(wavelengths, y)

extent=(np.min(wavelengths), np.max(wavelengths), np.min(y), np.max(y))

plt.imshow(X, clim=clim,  extent=extent, cmap=spectralmap, aspect='auto')
plt.xlabel('Wavelength (nm)')
plt.ylabel('Reflectance (%)')

plt.fill_between(wavelengths, spectrum, 8, color='w')
plt.savefig('WavelengthColors.png', dpi=600)

plt.show()

很遗憾,我无法 运行 您的代码,因为我没有 'Reflexionsspektren.xlsx' 文件。 但是,我相信基于此 post 的骇人听闻的解决方案会得到预期的结果。 我使用 np.vectorize 将您的 wavelength_to_rgb 函数转换为 x 轴上每个波长值的颜色数组。 使用 matplotlib 的 fill_between 在曲线和 x 轴之间绘制光谱。

import matplotlib.pyplot as plt
import numpy as np

def wavelength_to_rgb(wavelength, gamma=0.8):
    wavelength = float(wavelength)
    if wavelength >= 380 and wavelength <= 750:
        A = 1.
    else:
        A=0.5
    if wavelength < 380:
        wavelength = 380.
    if wavelength >750:
        wavelength = 750.
    if wavelength >= 380 and wavelength <= 440:
        attenuation = 0.3 + 0.7 * (wavelength - 380) / (440 - 380)
        R = ((-(wavelength - 440) / (440 - 380)) * attenuation) ** gamma
        G = 0.0
        B = (1.0 * attenuation) ** gamma
    elif wavelength >= 440 and wavelength <= 490:
        R = 0.0
        G = ((wavelength - 440) / (490 - 440)) ** gamma
        B = 1.0
    elif wavelength >= 490 and wavelength <= 510:
        R = 0.0
        G = 1.0
        B = (-(wavelength - 510) / (510 - 490)) ** gamma
    elif wavelength >= 510 and wavelength <= 580:
        R = ((wavelength - 510) / (580 - 510)) ** gamma
        G = 1.0
        B = 0.0
    elif wavelength >= 580 and wavelength <= 645:
        R = 1.0
        G = (-(wavelength - 645) / (645 - 580)) ** gamma
        B = 0.0
    elif wavelength >= 645 and wavelength <= 750:
        attenuation = 0.3 + 0.7 * (750 - wavelength) / (750 - 645)
        R = (1.0 * attenuation) ** gamma
        G = 0.0
        B = 0.0
    else:
        R = 0.0
        G = 0.0
        B = 0.0
    return (R,G,B,A)

if __name__ == '__main__':
    x = np.linspace(350, 780, 430)
    y = np.sin(x / 100)  # replace with your function / measured values.
    colors = np.array(np.vectorize(wavelength_to_rgb)(x))
    fig, ax = plt.subplots()
    ax.plot(x, y, color="gray")
    for i in range(len(x) - 1):
        plt.fill_between([x[i], x[i+1]], [y[i], y[i+1]], color=colors[:, i])