【问题标题】:Transparency for specific values in matrix using Gnuplot while preserving the palette?在保留调色板的同时使用 Gnuplot 矩阵中特定值的透明度?
【发布时间】:2014-08-19 17:20:32
【问题描述】:

这是一个有趣的问题:

我有一个双精度二进制数据的二维“矩阵”,我想使用 Gnuplot 进行绘图。这很容易做到,如下所示:

plot "foo.dat" binary array=384x384 format='%double' with image

诀窍在于数据的某些“区域”具有特殊值,例如 1234567890.0。我希望这些元素完全透明,而所有其他矩阵元素完全不透明。有没有办法根据数据本身设置透明度通道?

我查看了 Gnuplot 文档 (link) 的相关部分,我认为我需要使用 with rgbalpha 样式,但我不确定它如何应用或如何正确映射透明度。

我也查看了这些示例 (link),但我不确定如何应用它。

我想知道这是否可以在单行中完成(如上),或者是否需要几行(如在二进制矩阵顶部绘制轮廓时)。

提前致谢!

更新

我想我会给后代举一些例子。在所有示例中,我使用以下序言:

set title "Basic Plot"   # Or as appropriate
set size square
set palette @MATLAB   # see <http://www.gnuplotting.org/matlab-colorbar-with-gnuplot/>
set cbrange [-100000:100000]    # This cbrange fits my data well enough
                                # I would LOVE an automated way to do this!
val = 1234567890.0      # For missing data

我的基本命令产生以下内容:

plot "foo.dat" binary array=384x384 format='%double' with image

我还尝试了@Christoph 的建议:将等于val 的值替换为NaN

plot "foo.dat" binary array=384x384 format='%double' \
    using ($1 == val ? NaN : $1) with image

我尝试使用rgbalpha 来真正控制透明度,它会产生以下结果:

plot "foo.dat" binary array=384x384 format='%double' \
    using 1:1:1:($1 == val ? 0 : 255) with rgbalpha

结论

前两种方法产生相似的结果。第一个很糟糕,因为它用错误的最大值弄乱了颜色图。第一个和第二个不足之处在于它们实际上并没有实现透明度(Gnuplot 中的“未定义”值不会自动赋予透明度)。最后一个很棒,因为它实际上控制透明度,但它是灰度的,并且没有像我想要的那样使用@MATLAB 调色板。

如果有人可以使等于val 的所有条目透明并且让颜色图正常工作,我会接受他们的回答。

***下一步要去哪里****

Gnuplot 文档提到了set datafile missing 命令 (link)。这看起来很有希望,但它似乎只适用于基于列的数据——而不是二进制文件。

我想回答我最初的问题的最佳方法是设置一组函数来模仿 rgbalpha 方法的每个“列”的给定调色板——如下所示:

red(z)   = <stuff>
green(z) = <stuff>
blue(z)  = <stuff> 
plot "foo.dat" binary array=384x384 format='%double' \
    using red($1):green($1):blue($1):($1 == val ? 0 : 255) with rgbalpha

如果这些函数以某种方式引用了当前调色板,则可以加分,因此调色板的细节不会硬编码到这三个函数中。 :-)

【问题讨论】:

  • Alpha 通道从 0 到 255:0 = 完全透明,255 = 完全不透明。将数据映射到透明度通道时,请使用 using 选项和适当的表达式。例如,在您链接的示例中,如果您的数据点等于 1234567890,using 1:2:3:($3 == 1234567890 ? 0 : 255) 会将透明度通道设置为 0(透明),如果不是,则设置为 255(不透明)。
  • 由于是二进制数据,没有三列数据,这样就不行了。我认为这是正确的想法,但并不完全正确?
  • 我不知道,为什么我的回答对你不起作用。我在Replacing Colors in Gnuplot Heat Maps (pm3d map) 中给出了类似的答案,NaN 的东西似乎也不起作用。我在 Windows 和 Linux 上使用 gnuplot 4.6.5 使用 pngpngcairowxt 终端测试了我的脚本,它总是运行良好。
  • 使用rgbalpha 样式也应该可以正常工作,但是着色变得更加复杂,因为您必须 1) 自己定义颜色函数(我在某个地方),2) 自己进行缩放(使用stats 并在此处删除未定义的值)3)如果您需要显示颜色框,请使用多图。这一切都可以完成,但是相当冗长。如果你能提供一个示例数据文件,我可以检查我是否可以让 NaN 的东西与这个数据文件一起工作。
  • @Christoph:您的答案没有正确的二进制数组语法,至少正如最初所说的那样。您的 1:2:... 语法可能适用于数据按列排列的 ascii 文件。这就是我编辑它的原因。如果您的意思是“为什么我对结果不满意”,我对您所说的感到满意。我得到的输出显示了 NaN 所在的深蓝色轮廓(上图 #2),但我希望那个蓝色是透明的。 (也许在写入 PNG 时它会呈现为透明度?我使用的是 X11。)我尝试使用 stats,但无法让它与二进制数据一起使用。

标签: plot undefined gnuplot transparency alpha-transparency


【解决方案1】:

您可以通过为相应的像素赋予“NaN”值来实现:

value = 123456789.0
plot "foo.dat" binary array=384x384 format='%double' \
     using ($1 == val ? NaN : $1) with image

请注意,这取决于所选的终端。它至少适用于wxtpdfcairopngcairopng,并且适用于x11postscript。我没有测试其他终端。

这是一个独立的示例。背景颜色设置为显示像素确实是透明的而不是白色的:

set xrange [0:1]
set yrange [0:1]
set isosamples 11
set samples 11
plot '++' using 1:2:($1 == 0.5 && $2 == 0.5 ? NaN : $1) with image

4.6.5的结果是:

使用您的示例数据文件,以下脚本可以正常工作并提供很好的结果:

set terminal pngcairo size 800,800
set output 'foo.png'
set size square

f(x)=1.5-4*abs(x)
set palette model RGB
set palette functions f(gray-0.75),f(gray-0.5),f(gray-0.25)

val = 1234567890.0

set autoscale xfix
set autoscale yfix
set cbrange [-10000:10000]
plot 'foo.dat' binary array=(512,512) format='%double' using ($1 == val ? NaN : $1) with image notitle

【讨论】:

  • 这绝对让我走上了正轨——用 NaN 替换值告诉 Gnuplot 值是未定义的,然后它会忽略它。它不像你写的那样工作:二进制文件没有“列”(或者更确切地说,Gnuplot 将它视为一个列),所以你的 using 1:2:&lt;stuff&gt; 应该是 using &lt;stuff&gt;
  • 我编辑了您的答案以解决我在上一条评论中描述的问题,并且即将接受您的答案。谢谢!
  • 我不完全确定你用调色板做了什么,但它看起来很棒! (此外,它实际上并没有做到“真正的”透明度,但这对于我的目的来说完全就足够了。:-))再次感谢 - 非常感谢!
  • 我没有对调色板做任何特别的事情。我从gnuplotting.org 获得了喷射调色板的功能。要获得真正的透明度,您必须使用set terminal pngcairo nobackground,请参阅this result
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-17
  • 2012-08-28
  • 2011-06-05
相关资源
最近更新 更多