如何用光谱颜色填充 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])
如何用相应的颜色填充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])