用gnuplot绘制可见光谱

8
所以我有这样一种数据。
3.500E2 -0.956862
...
10.00E2 -1.95941

在一个文件中。

如果我绘制它,它看起来像这样:

带有线条的gnuplot图

现在我想用可见光谱填充曲线下的区域,就像这样:

可见光谱填充的曲线

我已经找到了这个论坛帖子,它为我绘制了一个漂亮的可见光谱,但是我无法将自己的曲线添加到其中,因为这似乎是一个pm3d图。

我该怎么办?


正如@OlivierT在已删除的答案中提到的那样:您可以在http://www.spectro-aras.com/forum/viewtopic.php?f=8&t=1000找到漂亮的gnuplot脚本。 - Christoph
如果您需要更精确的颜色,请参考真实光谱颜色 - Spektre
3个回答

7
filledcurves 绘图样式无法处理这种渐变填充,但您可以修改数据文件以在 pm3dsplot 中使用它。 pm3d 样式仅适用于表面,因此您必须编辑数据文件以实际提供表面网格。
为此,您必须向文件添加第二个数据块,该数据块具有第一列中的相同值,并将第二列的所有值的最小值作为其第二列。两个块之间必须用空行分隔。
请考虑示例数据文件 spectrum.dat
350 1
400 2
450 5
500 2
550 1
600 3
650 3
700 8
750 4
800 3
850 0

你必须从中获得一个文件

350 1
400 2
450 5
500 2
550 1
600 3
650 3
700 8
750 4
800 3
850 0

350 0
400 0
450 0
500 0
550 0
600 0
650 0
700 0
750 0
800 0
850 0

使用awk即可实现实时处理(由于@TomFenech的优化,该命令变得更好),然后使用来自您链接的论坛帖子中的函数定义,使用pm3d进行绘图:

lmax = 780; lmin = 380
k=lmax-lmin
set cbrange [lmin:lmax]
r(x)=x<440?-(x-440)/(440-380):x<510?0:x<580?(x-510)/(580-510):x<=780?1:0
g(x)=x<440?0:x<490?(x-440)/(490-440):x<580?1:x<645?-(x-645)/(645-580):0
b(x)=x<490?1:x<510?-(x-510)/(510-490):0
f(x)=x<420?0.3+0.7*(x-380)/(420-380):x<700?1:0.3+0.7*(780-x)/(780-700)
set palette functions f(k*gray+lmin)*r(k*gray+lmin),g(k*gray+lmin),f(k*gray+lmin)*b(k*gray+lmin)

set pm3d map interpolate 0,1
set autoscale xfix
splot '<awk ''NR == FNR {min = !min || $2 < min ? $2 : min; print; next} FNR == 1 {print ""} {$2 = min}1'' spectrum.dat spectrum.dat' using 1:2:(0):1 notitle

输入图像描述

请注意,如果您有足够的数据点,则不需要插值pm3d调色板。在这种情况下,这可能只会给您带来奇怪的伪影(白色垂直线)。


2
不错。您可以将 awk 缩短为以下形式:'NR == FNR {min = !min || $2 < min ? $2 : min; print; next} FNR == 1 {print ""} {$2 = min}1' - Tom Fenech
1
第一个代码块仅在第一个文件上运行。next 意味着从下一行重新开始,这样所有后续的代码块都不会在第一个文件上运行。代码块后面的 1 相当于在代码块末尾加上 print - Tom Fenech
2
没问题。如果你执行 set pm3d map interpolate 0,0,它还会使你的频谱看起来更加平滑。 - Tom Fenech
@TomFenech 没错 :) 如果您不介意,我会把您的两个建议都放在我的答案中。 - Christoph
2
感谢您的所有答案,这就是它的样子。 链接 - fsp
显示剩余5条评论

2

每当我想绘制VIS光谱时,就会遇到这个问题。我对@Christoph的回答进行了一些详细说明,并希望将颜色部分简化。使用HSV空间而非RGB是完全可行的,而且还可以简单计算吸收光谱的互补颜色。

gnuplot中的色相角必须在0:1范围内,而其他来源则为0-360。 0度对应于红色(假定为780nm)。 紫外边缘在色相空间的300度处。

Gnuplot会自动将输入数据缩放到cbrange范围内,因此我们需要将cbrange最大值设置为紫外线深处,并削减色相中品红部分(在300度 = 0.83 gnuplot Hue处)。 最后,色相与波长成反比例关系,因此调色板函数为(1-gray),饱和度和明度设置为常量0.5。

lmax = 780; lmin = 330
hmax=0.83
cbmax=lmax-((lmax-lmin)/hmax)

set cbrange [lmin:lmax]
h(x)=(x>hmax)?hmax:x
set palette model HSV functions h(1-gray),0.5,0.5

set pm3d map interpolate 0,1
splot '<awk ''NR == FNR {min = !min || $2 < min ? $2 : min; print; next} FNR == 1 {print ""} {$2 = min}1'' spectrum.dat spectrum.dat' using 1:2:(0):1 notitle

剧情的其余部分是相同的。

1
这里提供一种替代方案。它使用colorbox作为背景(类似于这里)。调色板可以随意调整。然而,这种解决方案有点作弊,因为它用一个白色填充曲线覆盖了未着色的区域。 数据: SO59238772.dat(来自Christoph的答案)
 350   1
 400   2
 450   5
 500   2
 550   1
 600   3
 650   3
 700   8
 750   4
 800   3
 850   0
脚本:(适用于gnuplot 4.6.0,2012年3月)
### spectrum with visible colors as background
reset 

FILE = "SO59238772.dat"

set palette defined (380 "black", 400 "dark-violet", 440 "blue",  490 '#00b0c0', \
                     530 "green", 560 "yellow", 620 "red", 780 "black")
unset cblabel
unset cbtics
set colorbox horizontal user origin graph 0, 0 size graph 1, 1 back
unset key
set xtics out
set ytics out
set grid x,y front
set xrange [380:780]

plot FILE u 1:2 w filledcurves x2 lc rgb "white", \
       (NaN) w p palette   # just to get the colorbox
### end of script

结果:

enter image description here

这是一个显示图像的HTML代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接