14

我一直在尝试更改 gnuplot 中填充曲线选项的填充样式,以便填充颜色表示二维图上两条曲线之间的差异。我认为这是“上/下填充曲线”选项的扩展,其中不仅有两种颜色代表上方或下方,还有颜色范围或调色板。

这是我想使用上/下填充曲线样式从数据文件制作的图示例。表示两条曲线之间的 y 差异的颜色条将非常有用。

http://i.stack.imgur.com/RLlpU.png

我试图通过在使用命令中添加第四列来做到这一点,即

plot 'data.txt' using 1:2:3:($3-$2) with filledcurves fs palette

filledcurves似乎不接受第四列......我也考虑过尝试 rgb 变量,但这似乎也不起作用。

4

8 回答 8

7

我正在玩 gnuplot 的补丁以允许使用linecolor rgb variable填充曲线。然后可以使用以下 gnuplot 代码:

max_color=1
# for a datafile one could extract the maximum diffference with e.g.
# stats 'hotcold.dat' using 1:($3-$2)
# max_color = (abs(STATS_min_y) > abs(STATS_max_y)) ? abs(STATS_min_y) : abs(STATS_max_y)

red(val) = (val < 0 ? abs(1+val/max_color) : 1)
green(val) = (1 - abs(val)/max_color)
blue(val) = red(-val)
rgb(val) = 65536*int(255*red(val)) + 256*int(255*green(val)) + int(255*blue(val))

set yrange[0:1]
set xrange[400:2500]
set samples 200

fhot(x) = 0.1*exp(-((x-400)/200)**2) + 0.8*exp(-((x-2000)/300)**2)
fcold(x) = 0.25*exp(-((x-700)/100)**6)+ 0.4 - (2e-4*(x-2500))**2
plot '+' using 1:(fhot($1)):(fcold($1)):(rgb(fhot($1)-fcold($1))) with filledcurves lc rgb var t '',\
     '' using 1:(fhot($1)) with lines lw 4 lc rgb rgb(max_color) t 'Hot',\
     '' using 1:(fcold($1)) with lines lw 4 lc rgb rgb(-max_color) t 'Cold'

这给出了这个结果: 在此处输入图像描述

我还没有提交补丁,因为我不知道我是否正确理解了这个问题,因为我不知道我是否涵盖了所有情况。所以可能需要一些微调。

于 2013-08-06T12:12:16.407 回答
2

尝试使用填充直方图。

set style fill solid 1.0
plot \
 datafile u 1:2:3 lt palette w boxes,\
 datafile u 1:2:3 lt palette lw 2 w l

第 3 列根据调色板设置定义颜色填充颜色,第 1 列和第 2 列定义数据点。您还可以使用背景颜色直方图来清除图形下的部分。

我想添加图像,但由于声誉低而无法添加。

于 2014-07-04T20:10:44.113 回答
1

AFAIK,这仍然没有在gnuplot. 但是,您可以通过覆盖几条透明填充曲线来解决脏(*)问题。

例如,

max_color=1
max_diff=0.5
N_col=6
TRSP="E0"
HOTCOL="FF0000"
COLDCOL="0000FF"
RGBA_HOT="#".TRSP.HOTCOL
RGBA_COLD="#".TRSP.COLDCOL
RGB_HOT="#".HOTCOL
RGB_COLD="#".COLDCOL
#red(val) = (val < 0 ? abs(1+val/max_color) : 1)
#green(val) = (1 - abs(val)/max_color)
#blue(val) = red(-val)
#rgb(val) = 65536*int(255*red(val)) + 256*int(255*green(val)) + int(255*blue(val))
fhot(x) = 0.1*exp(-((x-400)/200)**2) + 0.8*exp(-((x-2000)/300)**2)
fcold(x) = 0.25*exp(-((x-700)/100)**6)+ 0.4 - (2e-4*(x-2500))**2
plot [400:2600] for [thr=0:N_col] '+' using (((fhot($1)-fcold($1))/max_diff*N_col>thr)?$1:1/0):(fhot($1)):(fcold($1)) with filledcurves lc rgb RGBA_HOT title '',\
     for [thr=0:N_col] '+' using ((-(fhot($1)-fcold($1))/max_diff*N_col>thr)?$1:1/0):(fhot($1)):(fcold($1)) with filledcurves lc rgb RGBA_COLD title '',\
     '' using 1:(fhot($1)) with lines lw 4 lc rgb RGB_HOT t 'Hot',\
     '' using 1:(fcold($1)) with lines lw 4 lc rgb RGB_COLD t 'Cold'

调整N_colTRSP更改渐变:覆盖的填充曲线的数量和每个曲线的透明度(更多曲线意味着更接近最大透明度FE)。

在此处输入图像描述

(*) 如果您要绘制的信息是离散变量,例如在给定横坐标处可用的数据集数量,这将不那么脏。

于 2020-09-25T10:15:39.427 回答
1

另一个解决方案

如果允许 pm3d 2D 地图没有填充曲线,那么可以使用以下代码来实现这一点

在数据处理部分,splot从原始输入数据构建网格数据。填充区域的颜色由为 splot 指定的 z 值确定。

set table $first
plot "test.dat" using 1:2:($3-$2) with table
set table $second
plot "test.dat" using 1:3:($3-$2) with table
unset table

set print $data
do for [i=1:|$first|] {
  print $first[i]
  print $second[i]
  print ""
}
set print

set yrange [-2:2]
set palette define (-1 "skyblue", 0 "gray90", 1 "pink")

splot $data using 1:2:3 with pm3d 
于 2020-10-25T06:29:32.570 回答
0

另一个尴尬的解决方法: 而不是filledcurves使用粗垂直矢量线。

当您具有示例中的函数或 x 中的等距数据时,这将起作用。如果 x 中没有等距数据,则必须进行插值。不幸的是,gnuplot 没有插值或重采样的功能。您可以使用外部工具执行此操作,也可以使用变得有点冗长的 gnuplot 来完成此操作,请参见此处:使用 gnuplot 重新采样数据

为了获得好看的颜色渐变,您必须调整图形/画布大小、采样和/或线宽,以找到消除间隙、悬垂或锯齿的最佳方法。太薄(lw 1)和太厚(lw 8)都不好。在下面的示例中lw 3似乎是一个合理的值。也许还有更多的方法可以进一步优化。

下面的示例使用@Christoph 的代码,稍作修改。

代码:

max_color=1
# for a datafile one could extract the maximum diffference with e.g.
# stats 'hotcold.dat' using 1:($3-$2)
# max_color = (abs(STATS_min_y) > abs(STATS_max_y)) ? abs(STATS_min_y) : abs(STATS_max_y)

red(val) = (val < 0 ? abs(1+val/max_color) : 1)
green(val) = (1 - abs(val)/max_color)
blue(val) = red(-val)
rgb(val) = 65536*int(255*red(val)) + 256*int(255*green(val)) + int(255*blue(val))

set yrange[0:1]
set xrange[400:2500]
set samples 200

fhot(x) = 0.1*exp(-((x-400)/200)**2) + 0.8*exp(-((x-2000)/300)**2)
fcold(x) = 0.25*exp(-((x-700)/100)**6)+ 0.4 - (2e-4*(x-2500))**2

plot \
     '+' using 1:(fhot($1)):(0):(fcold($1)-fhot($1)):(rgb(fhot($1)-fcold($1))) with vectors nohead lw 3 lc rgb var t '',\
     '' using 1:(fhot($1)) with lines lw 4 lc rgb rgb(max_color) t 'Hot',\
     '' using 1:(fcold($1)) with lines lw 4 lc rgb rgb(-max_color) t 'Cold'
     

结果:(wxt 640x480,lw 1) 在此处输入图像描述

结果:(wxt 640x480,lw 3)

在此处输入图像描述

结果:(wxt 640x480,lw 8) 在此处输入图像描述

于 2020-09-25T13:32:09.697 回答
0

而不是@luuuucky 建议的填充直方图,您可以使用boxxyerror将矩形放置在任何地方并用可变颜色为它们着色。

这是一个简单的示例,其中的数据包含x,y1,y2间距x一致的三元组。盒子根据以下颜色着色y2-y1

set style fill solid
set palette gray

set cbrange [0:1]
set xrange [0:1]
set yrange [0:1]

plot '-' using 1:2:1:($1+0.1):2:3:($3-$2) with boxxyerror lc palette notitle
0.0 0.62 0.82
0.1 0.64 0.94
0.2 0.51 0.91
0.3 0.33 0.83
0.4 0.20 0.63
0.5 0.15 0.43
0.6 0.10 0.23
0.7 0.05 0.13
0.8 0.03 0.10
0.9 0.02 0.05

带有 boxxyerror 的伪彩色填充曲线 自然,精细的x离散化会导致更平滑的结果。这是一个数值模拟的例子,一个压缩弹簧的两个末端 s1(t) 和 s2(t) 在各向异性环境中随时间机械松弛(颜色 = 机械力) 在此处输入图像描述

于 2022-02-03T14:05:09.030 回答
0

(另一种)开发版本 5.5 的新方法

开发版有一个新的机制masking。这里我们首先将整个图形的填充区域创建为image,然后将所需区域之外的所有内容都隐藏起来,即不可见。遮蔽区域是一个(复杂的)多边形,我们必须分两步构建它:首先,在正常绘图方向上创建上边界作为两个数据集的较大值,然后下边界需要向后创建作为最小值,以便最终创建适当的多边形。出于说明目的,我使用了@Christoph's answer中的函数并将它们转换为一个看起来像 OP 数据文件的数据集:

set yrange[0:1]
set xrange[400:2500]
set ur [400:2500]
set vr [0:1]
set samples 1000
set isosamples 1000
fhot(x) = 0.1*exp(-((x-400)/200)**2) + 0.8*exp(-((x-2000)/300)**2)
fcold(x) = 0.25*exp(-((x-700)/100)**6)+ 0.4 - (2e-4*(x-2500))**2

set table $data
plot '+' u 1:(fhot($1)):(fcold($1)) w table
unset table

现在计算上下边界:

set table $upper
plot $data u 1:($2>=$3 ? $2 : $3) w table
unset table

# gnuplot has no build-in "backwards" plotting
set table $lower
plot for [i=1:|$data|] $data every ::(|$data|-i)::(|$data|-i) u 1:($2<=$3 ? $2 : $3) w table
unset table

set table $mask
plot $upper w table
plot $lower w table
unset table

我发现一个完全不透明的调色板太多了,因此让我们定义一个新的、半透明的调色板:

set palette defined (-1 "blue", 0 "white", 1 "red")
set colormap new MYPALETTE
do for [i=1:|MYPALETTE|] {MYPALETTE[i] = MYPALETTE[i] + (int(0.5*0xff)<<24)}
unset colorbox

现在在实际的绘图命令中,第一个元素是掩蔽数据,它本身不会绘制任何东西,而是为绘图的下一个元素做准备:

plot $mask w mask not, '++' u 1:2:(fhot($1)-fcold($1)) mask w image fc palette MYPALETTE not, fhot(x) lc "red" lw 3, fcold(x) lc "blue" lw 3

在此处输入图像描述

于 2022-02-23T16:45:23.013 回答
-3

诀窍是画线,然后在它们之间填充filledcurves. 以下是如何做到这一点(基于gnuplot 的示例):

set style line 2 lc rgb 'forest-green'
set style line 3 lc rgb 'plum'
set style fill pattern 5 lc 'yellow'
set xrange [0:3000]
set yrange [0:1]
plot 'data.txt' u 1:2:3 w filledcurves notitle, \
     '' u 1:2 ls 2 with lines notitle, \
     '' u 1:3 ls 3 with lines notitle

输出如下所示: 在此处输入图像描述

数据文件包含这些虚拟值(类似于您的第二个图表):

500     0.90    0.90
1000    0.90    0.75
1500    0.92    0.40
2000    0.95    0.30
2500    0.94    0.23
于 2013-04-23T08:46:35.130 回答