I would like to make a plot of of a spectrum, where the area under the curve will be shaded according the the corresponding color of the light. Much like this plot:
I have tried to emulate this in matplotlib, by using imshow
with the spectral
colormap to plot the colors, and a white fill_between
to cover up the region above the curve. I am fairly happy with the result, except for two things:
1) The colors that I am plotting do not quite align with the visible spectrum. For example I show 700 nm as yellow/orange, when it is red. I am happy with a somewhat stylized representation (for example, I think that the accurate colors shown in the second answer here are boring), but in general, I would like to wavelengths to align with their visible colors.
2) I like how the spectrum above has the regions outside of the visible region colored with alpha<1.0. I am not sure how to achieve this.
Here is what I have so far:
import numpy as np
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1, 1, figsize=(8,4), tight_layout=True)
wavelengths = np.linspace(200, 1000, 1000)
spectrum = (5 + np.sin(wavelengths*0.1)**2) * np.exp(-0.00002*(wavelengths-600)**2)
plt.plot(wavelengths, spectrum, color='darkred')
y = np.linspace(0, 6, 100)
X,Y = np.meshgrid(wavelengths, y)
X[X<400] = 400
extent=(np.min(wavelengths), np.max(wavelengths), np.min(y), np.max(y))
plt.imshow(X, clim=(350,820), extent=extent, cmap=plt.get_cmap('spectral'), aspect='auto')
plt.xlabel('Wavelength (nm)')
plt.ylabel('Intensity')
plt.fill_between(wavelengths, spectrum, 8, color='w')
plt.savefig('WavelengthColors.png', dpi=200)
plt.show()
First of all you would need a function that takes the wavelength as input and returns an RGB color. Such a function can be found here. One may adapt it to also return an alpha value, which is smaller 1 outside the range of visible colors.
This function can be used to make create a colormap. Using a decent normalization allows to have the range of wavelengths mapped to the range between 0 and 1, such that this colormap may be used in an imshow plot.