- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想绘制一个光谱图,其中曲线下方的区域将根据相应的光颜色进行着色。很像这个情节:
我试图在 matplotlib 中模拟这一点,方法是使用 imshow
和 spectral
颜色图来绘制颜色,并使用白色 fill_between
来绘制颜色掩盖曲线上方的区域。我对结果相当满意,除了两件事:
1) 我绘制的颜色与可见光谱不太一致。例如,当它是红色时,我将 700 nm 显示为黄色/橙色。我对有点程式化的表示感到满意(例如,我认为第二个答案 here 中显示的准确颜色很无聊),但总的来说,我希望波长与其可见颜色对齐。
2) 我喜欢上面的光谱如何将可见区域之外的区域着色为 alpha<1.0。我不确定如何实现这一目标。
这是我目前所拥有的:
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()
最佳答案
首先,您需要一个将波长作为输入并返回 RGB 颜色的函数。可以找到这样的功能here .可以调整它以返回一个 alpha 值,该值在可见颜色范围之外小于 1。
此函数可用于创建颜色图。使用适当的归一化可以将波长范围映射到 0 到 1 之间的范围,这样就可以在 imshow 图中使用该颜色图。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
def wavelength_to_rgb(wavelength, gamma=0.8):
''' taken from http://www.noah.org/wiki/Wavelength_to_RGB_in_Python
This converts a given wavelength of light to an
approximate RGB color value. The wavelength must be given
in nanometers in the range from 380 nm through 750 nm
(789 THz through 400 THz).
Based on code by Dan Bruton
http://www.physics.sfasu.edu/astro/color/spectra.html
Additionally alpha value set to 0.5 outside range
'''
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=(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)
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('Intensity')
plt.fill_between(wavelengths, spectrum, 8, color='w')
plt.savefig('WavelengthColors.png', dpi=200)
plt.show()
关于python - Matplotlib - 基于光谱颜色的曲线下颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44959955/
使用 Redshift 光谱时,您似乎只能导入提供位置直到文件夹的数据,并且导入文件夹内的所有文件。 有没有办法从包含多个文件的文件夹中导入仅导入一个文件。当提供带有 filename 的完整路径时,
我正在评估 Athena 和 Redshift Spectrum。两者都有相同的目的,Spectrum 需要一个 Redshift 集群,而 Athena 是纯粹的无服务器集群。 Athena 使用
我们目前生成每日 CSV 导出,并将其上传到 S3 存储桶,结构如下: |--reportDate- |-- part0.csv.gz |-- part1.csv.gz 我们希望能够
我在 S3 中有一个 JSON 结构数组,它已被 Glue 成功抓取和编目。 [{"key":"value"}, {"key":"value"}] 我正在使用自定义分类器: $[*] 然而,当尝试从
我是一名优秀的程序员,十分优秀!