Gnuplot 绘制颜色
Gnuplot plotting colours
我正在尝试制作一张 RGB 值与颜色的图表,如下图所示:
我的方法基于 http://gnuplot.sourceforge.net/demo/pm3dcolors.html
为此,重要的是能够正确显示任意数量的颜色,并与绘图对齐。
在上图中,您可以看到颜色之间有些奇怪的重叠,并且宽度不同,并且与图表不太一致。
此 post 的其余部分演示了使其看起来怪异所需的最低要求。
我发现它在 33 种颜色后开始变得混乱。
#!/usr/bin/env gnuplot
set format cb "%3.1f"
set style function pm3d
set view map scale 1
unset xtics
unset ytics
unset ztics
unset colorbox
unset key
set title "33 colours"
set palette model RGB
set palette file "-"
1 0 0
0 1 0
0 0 1
... repeat many times ...
1 0 0
0 1 0
0 0 1
e
set palette maxcolors 33
g(x)=x
splot g(x)
pause mouse any "press the any key to exit gnuplot
- 这是 33 种及以下颜色的情况:
- 这是 34 的情况(中间的绿色较窄):
- 如果我们增加到 66,您会发现更多错误:
总的来说,这显然是对 gnuplot 的滥用。
还有其他更好的方法吗?
如果没有,我应该如何调试它?
我是 运行 来自 debian bullseye 上的 debian repos 的 gnuplot 5.4 补丁级别 1。
感谢您的任何建议。
编辑:
我掉进了XY问题的陷阱。
我希望问题中的第一个图表没有奇怪的东西,比如你如何看到不同的颜色宽度,而当它们都应该是相同的宽度时。
我询问了我发现用设置调色板显示我看到的奇怪事物的最少方法。
我当前的输入数据是这样的:
Hue, Red, Green, Blue
0.0100, 255, 15, 0
0.0300, 255, 46, 0
0.0400, 255, 61, 0
0.0600, 255, 92, 0
0.0700, 255, 107, 0
...
我生成该图的脚本是 http://ix.io/3BE2
如果我对你尝试过的东西的描述没有理解错的话,它们都是基于调色板定义选项set palette defined
。这本质上受范围插值伪影的影响,尽管随着您增加调色板定义中使用的增量数量,伪影变得不那么明显。
由于您的主要目标是“能够正确显示任意数量的颜色”,您最好使用不同的方法来定义调色板,一种基于 RGB 的一组连续函数组件。而你 而不是 想要使用 set palette maxcolors
,因为该命令的全部意义在于将调色板限制为一组离散的颜色而不是连续体。
一个预定义的选项是使用set palette cubehelix
,它使用一组固定的连续函数,但允许您调整各种控制参数。例如 set palette cubehelix start 0.15 cycles 1.0 saturation 1.0
生成下面的调色板。然而,这个调色板系列的定义 属性 是强度从 0 到 1,这可能是您不想要的。
一个更通用的解决方案是为调色板定义提供您自己的连续函数。例如,set palette model HSV functions gray, 1, 0.9
生成下面的调色板。这与您展示的基本相同,只是它是根据连续函数定义的。
请注意,test palette
的输出在底部的颜色条中仅显示 128 个样本。但这并不是调色板的内在限制,它只是为了方便生成测试输出而选择的。我将尝试显示区别(不确定它是否会在此网站上显示)
set palette model HSV functions gray, 1, 0.9
set colorbox horiz user origin 0.05, 0.01 size 0.9, 0.05
set lmargin at screen 0.05; set rmargin at screen 0.95
unset ytics
set title "x sampling 1000 intervals"
set cblabel "colorbox sampling 128 intervals" norotate offset 0,1.5
set view map
set sample 1000
splot x with pm3d
您可能还需要担心您正在制作的文档所使用的颜色系统的限制。并非所有输出格式都可以使用完整的 24 位 RGB 颜色规范。 pdf/svg/cairo 应该没问题。另一方面,旧式颜色索引 gif 或 png 总共限制为 256 种不同的颜色。
替代答案试图解决修改后的问题
修改后的问题:
Thanks for your reply but by "display an arbitrary number of colors" I meant that I have a list of colors and I want to display them, I don't have a way to represent them as a function.
# snippet of code from your attachment
set palette file 'plotData/rgb.csv' using ((/255)):((/255)):(()/255)
set palette maxcolors system("wc -l plotData/rgb.csv | sed 's/ .*//'")
g(x)=x
splot g(x)
我将首先指出这种方法的一些问题。我仍然不太明白输出的要求是什么,但我收集到的部分问题是它不会产生一组与调色板颜色数量相匹配的均匀间隔区域。这是可以理解的,因为
- 只有通过计算外部文件中的行数才能知道颜色数 Ncol。
- 由
splot F(x)
生成的沿x的填充区间数由set samples
决定,它与Ncol没有内在联系。
- 您可以尝试通过说
set samples Ncol
来对齐两者,但这仍然允许沿 x 轴的区间边界与沿颜色轴 cb 的区间边界不匹配。可能您可以通过修复 set xrange [A:B]; set cbrange [A:B]
来解决此问题,但这需要提前知道限制值 A 和 B。此外,在大多数应用程序中,x 上理想的空间分辨率很可能远大于索引调色板支持的颜色数量。
我建议您真的根本不需要调色板。您只需要 RGB 颜色值。这里有两个基于上面代码片段的变体
# convert file of numerical RGB components (0-255) to 24-bit hex representation
# $RGBtable will be a datablock containing Ncol string values
set table $RGBtable
plot 'rgbvalues.csv' using (sprintf("0x%2x%2x%2x", , , )) with table
unset table
Ncol = |$RGBtable|
# create an array containing the same set of colors as integer values
array RGBarray[Ncol]
do for [i=1:Ncol] { RGBarray[i] = int($RGBtable[i]) }
# Now we can use either the string form or the integer form to plot with.
# I still don't understand exactly what it is you are plotting, but here
# is an example using either the datablock or the array to access colors
set xrange [0 : Ncol+1]
set yrange [0 : 3]
plot sample [i=1:Ncol] '+' using 1:(1):(RGBarray[i]) with points pt 5 lc rgb variable, \
[i=1:Ncol] '+' using 1:(2):(int($RGBtable[i])) with points pt 7 lc rgb variable
最后,这里有一个类似于您的原始 splot 命令的东西,它使用沿水平方向的高分辨率采样,但是一组来自 [1:Ncol] 范围内整数值的离散颜色。
请注意,using
说明符的字段 3 中的标称 z 值与此图无关,因为颜色信息是根据 lc rgb variable
.
的要求与字段 4 分开提供的
set view map
set sample 999
set urange [1:Ncol]
splot '++' using 1:2:(0):(RGBarray[int()]) with pm3d lc rgb variable
我正在尝试制作一张 RGB 值与颜色的图表,如下图所示:
我的方法基于 http://gnuplot.sourceforge.net/demo/pm3dcolors.html
为此,重要的是能够正确显示任意数量的颜色,并与绘图对齐。
在上图中,您可以看到颜色之间有些奇怪的重叠,并且宽度不同,并且与图表不太一致。
此 post 的其余部分演示了使其看起来怪异所需的最低要求。
我发现它在 33 种颜色后开始变得混乱。
#!/usr/bin/env gnuplot
set format cb "%3.1f"
set style function pm3d
set view map scale 1
unset xtics
unset ytics
unset ztics
unset colorbox
unset key
set title "33 colours"
set palette model RGB
set palette file "-"
1 0 0
0 1 0
0 0 1
... repeat many times ...
1 0 0
0 1 0
0 0 1
e
set palette maxcolors 33
g(x)=x
splot g(x)
pause mouse any "press the any key to exit gnuplot
- 这是 33 种及以下颜色的情况:
- 这是 34 的情况(中间的绿色较窄):
- 如果我们增加到 66,您会发现更多错误:
总的来说,这显然是对 gnuplot 的滥用。
还有其他更好的方法吗? 如果没有,我应该如何调试它?
我是 运行 来自 debian bullseye 上的 debian repos 的 gnuplot 5.4 补丁级别 1。
感谢您的任何建议。
编辑:
我掉进了XY问题的陷阱。 我希望问题中的第一个图表没有奇怪的东西,比如你如何看到不同的颜色宽度,而当它们都应该是相同的宽度时。 我询问了我发现用设置调色板显示我看到的奇怪事物的最少方法。
我当前的输入数据是这样的:
Hue, Red, Green, Blue
0.0100, 255, 15, 0
0.0300, 255, 46, 0
0.0400, 255, 61, 0
0.0600, 255, 92, 0
0.0700, 255, 107, 0
...
我生成该图的脚本是 http://ix.io/3BE2
如果我对你尝试过的东西的描述没有理解错的话,它们都是基于调色板定义选项set palette defined
。这本质上受范围插值伪影的影响,尽管随着您增加调色板定义中使用的增量数量,伪影变得不那么明显。
由于您的主要目标是“能够正确显示任意数量的颜色”,您最好使用不同的方法来定义调色板,一种基于 RGB 的一组连续函数组件。而你 而不是 想要使用 set palette maxcolors
,因为该命令的全部意义在于将调色板限制为一组离散的颜色而不是连续体。
一个预定义的选项是使用set palette cubehelix
,它使用一组固定的连续函数,但允许您调整各种控制参数。例如 set palette cubehelix start 0.15 cycles 1.0 saturation 1.0
生成下面的调色板。然而,这个调色板系列的定义 属性 是强度从 0 到 1,这可能是您不想要的。
一个更通用的解决方案是为调色板定义提供您自己的连续函数。例如,set palette model HSV functions gray, 1, 0.9
生成下面的调色板。这与您展示的基本相同,只是它是根据连续函数定义的。
请注意,test palette
的输出在底部的颜色条中仅显示 128 个样本。但这并不是调色板的内在限制,它只是为了方便生成测试输出而选择的。我将尝试显示区别(不确定它是否会在此网站上显示)
set palette model HSV functions gray, 1, 0.9
set colorbox horiz user origin 0.05, 0.01 size 0.9, 0.05
set lmargin at screen 0.05; set rmargin at screen 0.95
unset ytics
set title "x sampling 1000 intervals"
set cblabel "colorbox sampling 128 intervals" norotate offset 0,1.5
set view map
set sample 1000
splot x with pm3d
您可能还需要担心您正在制作的文档所使用的颜色系统的限制。并非所有输出格式都可以使用完整的 24 位 RGB 颜色规范。 pdf/svg/cairo 应该没问题。另一方面,旧式颜色索引 gif 或 png 总共限制为 256 种不同的颜色。
替代答案试图解决修改后的问题
修改后的问题:
Thanks for your reply but by "display an arbitrary number of colors" I meant that I have a list of colors and I want to display them, I don't have a way to represent them as a function.
# snippet of code from your attachment
set palette file 'plotData/rgb.csv' using ((/255)):((/255)):(()/255)
set palette maxcolors system("wc -l plotData/rgb.csv | sed 's/ .*//'")
g(x)=x
splot g(x)
我将首先指出这种方法的一些问题。我仍然不太明白输出的要求是什么,但我收集到的部分问题是它不会产生一组与调色板颜色数量相匹配的均匀间隔区域。这是可以理解的,因为
- 只有通过计算外部文件中的行数才能知道颜色数 Ncol。
- 由
splot F(x)
生成的沿x的填充区间数由set samples
决定,它与Ncol没有内在联系。 - 您可以尝试通过说
set samples Ncol
来对齐两者,但这仍然允许沿 x 轴的区间边界与沿颜色轴 cb 的区间边界不匹配。可能您可以通过修复set xrange [A:B]; set cbrange [A:B]
来解决此问题,但这需要提前知道限制值 A 和 B。此外,在大多数应用程序中,x 上理想的空间分辨率很可能远大于索引调色板支持的颜色数量。
我建议您真的根本不需要调色板。您只需要 RGB 颜色值。这里有两个基于上面代码片段的变体
# convert file of numerical RGB components (0-255) to 24-bit hex representation
# $RGBtable will be a datablock containing Ncol string values
set table $RGBtable
plot 'rgbvalues.csv' using (sprintf("0x%2x%2x%2x", , , )) with table
unset table
Ncol = |$RGBtable|
# create an array containing the same set of colors as integer values
array RGBarray[Ncol]
do for [i=1:Ncol] { RGBarray[i] = int($RGBtable[i]) }
# Now we can use either the string form or the integer form to plot with.
# I still don't understand exactly what it is you are plotting, but here
# is an example using either the datablock or the array to access colors
set xrange [0 : Ncol+1]
set yrange [0 : 3]
plot sample [i=1:Ncol] '+' using 1:(1):(RGBarray[i]) with points pt 5 lc rgb variable, \
[i=1:Ncol] '+' using 1:(2):(int($RGBtable[i])) with points pt 7 lc rgb variable
最后,这里有一个类似于您的原始 splot 命令的东西,它使用沿水平方向的高分辨率采样,但是一组来自 [1:Ncol] 范围内整数值的离散颜色。
请注意,using
说明符的字段 3 中的标称 z 值与此图无关,因为颜色信息是根据 lc rgb variable
.
set view map
set sample 999
set urange [1:Ncol]
splot '++' using 1:2:(0):(RGBarray[int()]) with pm3d lc rgb variable