So I have this kind of data
3.500E2 -0.956862
...
10.00E2 -1.95941
in a file.
If I plot it it looks like this:
Now I want the area under the curve filled with the visible spectrum, like this:
I already found this forum post, which draws me a nice visible spectrum, but I can't further add my own curve into it, as this appears to be a pm3d plot.
What can I do?
The filledcurves
plotting style cannot handle such gradient filling, but you can modify your data file to use it with pm3d
and splot
.
The pm3d
style works only for surfaces, so you must edit your data file to actually provide a surface grid.
For this you must add a second data block to your file, which has the same values in the first column, and the minimum of all values of the second column as its second column. Both blocks must be separated by an empty line.
Consider the example data file spectrum.dat
:
350 1
400 2
450 5
500 2
550 1
600 3
650 3
700 8
750 4
800 3
850 0
From that you must get a file
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
That can be done on-the-fly with awk (the command got much better thanks to @TomFenech) and then plotted with pm3d
using the function definitions from the forum post you linked:
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
Note, that you don't need to interpolate the pm3d palette if you have enough data points. That might only give you strange artifacts (white vertical lines) in that case.
I regularly hit this question whenever I want to plot the VIS spectrum. I elaborated a bit over the answer by @Christoph and wanted to make the color part simpler. Which is indeed possible, using the HSV space, instead of RGB. In addition, it allows simple calculation of complementary color for absorption spectra.
The hue angle gnuplot must be in range 0:1, in all other sources 0-360. The angle 0 corresponds to red (assumed 780nm). The ultraviolet edge is at 300 degree of hue space.
Gnuplot automatically scales the input data into the cbrange, so we need to put the cbrange maximum deep into the UV and cut off the magenta part of Hue (at 300 degree = 0.83 gnuplot Hue). Finally, the hue is inversely proportional to th wavelength, so the palette function is (1-gray), the Saturation and Value are set to constant 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
The rest of the plot is identical
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With