gnuplot:应用来自数据文件的颜色名称

5

我该如何从数据文件中获取颜色名称? 我没有预料到这会很困难,但显然它确实是。 为什么版本1和版本2给出错误的颜色?有没有更简单的方法来获得正确的颜色,而不使用类似版本3中的数组?并且...lc var只适用于索引值,而不适用于颜色名称。

### colornames from data
reset session

$Data <<EOD
1   40  orange
2   35  cyan
3   25  red
4   15  yellow
5   5   green
EOD

set yrange [0:]
set multiplot layout 3,1
MyColor = "black"
plot \
    $Data u 1:(MyColor=strcol(3),$2):(0.7) w boxes fs solid 1.0 lc rgb MyColor notitle,\
    $Data u 1:($2/2):(strcol(3)) with labels tc rgb "white" notitle

plot \
    for [i=1:|$Data|] $Data u (MyColor=strcol(3),$1):2:(0.7) every ::i-1::i-1 w boxes fs solid 1.0 lc rgb MyColor notitle,\
    $Data u 1:($2/2):(strcol(3)) with labels notitle

array MyColors[|$Data|]
plot \
    $Data u (NaN):(MyColors[$0+1]=strcol(3)) notitle,\
    for [i=1:|$Data|] $Data u 1:2:(0.7) every ::i-1::i-1 w boxes fs solid 1.0 lc rgb MyColors[i] notitle,\
    $Data u 1:($2/2):(strcol(3)) with labels notitle

print MyColors
unset multiplot
### end of code

enter image description here

3个回答

19

如果有人想使用查找表,就像@Ethan建议的那样,在这里是包含111个预定义gnuplot颜色的数组(取自gnuplot手册)。

array ColorNames[111] = \
['white', 'black', 'dark-grey', 'red', 'web-green', 'web-blue', 'dark-magenta', 'dark-cyan', 'dark-orange', 'dark-yellow', \
'royalblue', 'goldenrod', 'dark-spring-green', 'purple', 'steelblue', 'dark-red', 'dark-chartreuse', 'orchid', 'aquamarine', 'brown', \
'yellow', 'turquoise', 'grey0', 'grey10', 'grey20', 'grey30', 'grey40', 'grey50', 'grey60', 'grey70', \
'grey', 'grey80', 'grey90', 'grey100', 'light-red', 'light-green', 'light-blue', 'light-magenta', 'light-cyan', 'light-goldenrod', \
'light-pink', 'light-turquoise', 'gold', 'green', 'dark-green', 'spring-green', 'forest-green', 'sea-green', 'blue', 'dark-blue', \
'midnight-blue', 'navy', 'medium-blue', 'skyblue', 'cyan', 'magenta', 'dark-turquoise', 'dark-pink', 'coral', 'light-coral', \
'orange-red', 'salmon', 'dark-salmon', 'khaki', 'dark-khaki', 'dark-goldenrod', 'beige', 'olive', 'orange', 'violet', \
'dark-violet', 'plum', 'dark-plum', 'dark-olivegreen', 'orangered4', 'brown4', 'sienna4', 'orchid4', 'mediumpurple3', 'slateblue1', \
'yellow4', 'sienna1', 'tan1', 'sandybrown', 'light-salmon', 'pink', 'khaki1', 'lemonchiffon', 'bisque', 'honeydew', \
'slategrey', 'seagreen', 'antiquewhite', 'chartreuse', 'greenyellow', 'gray', 'light-gray', 'light-grey', 'dark-gray', 'slategray', \
'gray0', 'gray10', 'gray20', 'gray30', 'gray40', 'gray50', 'gray60', 'gray70', 'gray80', 'gray90', \
'gray100']
 
array ColorValues[111] = \
[0xffffff, 0x000000, 0xa0a0a0, 0xff0000, 0x00c000, 0x0080ff, 0xc000ff, 0x00eeee, 0xc04000, 0xc8c800, \
0x4169e1, 0xffc020, 0x008040, 0xc080ff, 0x306080, 0x8b0000, 0x408000, 0xff80ff, 0x7fffd4, 0xa52a2a, \
0xffff00, 0x40e0d0, 0x000000, 0x1a1a1a, 0x333333, 0x4d4d4d, 0x666666, 0x7f7f7f, 0x999999, 0xb3b3b3, \
0xc0c0c0, 0xcccccc, 0xe5e5e5, 0xffffff, 0xf03232, 0x90ee90, 0xadd8e6, 0xf055f0, 0xe0ffff, 0xeedd82, \
0xffb6c1, 0xafeeee, 0xffd700, 0x00ff00, 0x006400, 0x00ff7f, 0x228b22, 0x2e8b57, 0x0000ff, 0x00008b, \
0x191970, 0x000080, 0x0000cd, 0x87ceeb, 0x00ffff, 0xff00ff, 0x00ced1, 0xff1493, 0xff7f50, 0xf08080, \
0xff4500, 0xfa8072, 0xe9967a, 0xf0e68c, 0xbdb76b, 0xb8860b, 0xf5f5dc, 0xa08020, 0xffa500, 0xee82ee, \
0x9400d3, 0xdda0dd, 0x905040, 0x556b2f, 0x801400, 0x801414, 0x804014, 0x804080, 0x8060c0, 0x8060ff, \
0x808000, 0xff8040, 0xffa040, 0xffa060, 0xffa070, 0xffc0c0, 0xffff80, 0xffffc0, 0xcdb79e, 0xf0fff0, \
0xa0b6cd, 0xc1ffc1, 0xcdc0b0, 0x7cff40, 0xa0ff20, 0xbebebe, 0xd3d3d3, 0xd3d3d3, 0xa0a0a0, 0xa0b6cd, \
0x000000, 0x1a1a1a, 0x333333, 0x4d4d4d, 0x666666, 0x7f7f7f, 0x999999, 0xb3b3b3, 0xcccccc, 0xe5e5e5, \
0xffffff]

补充: 只是为了完整性和说明... 以下是一些用于生成预定义Gnuplot颜色概述的代码。

编辑: 代码已清理,并修改为与Gnuplot 4.6(当时没有数组和位移)兼容。

代码:

### display all predefined gnuplot colors, gnuplot >=4.6.0
reset
set term wxt size 1000,700 enhanced   # or change to another terminal

ColorNames = '\
white black dark-grey red web-green web-blue dark-magenta dark-cyan dark-orange dark-yellow \
royalblue goldenrod dark-spring-green purple steelblue dark-red dark-chartreuse orchid aquamarine brown \
yellow turquoise grey0 grey10 grey20 grey30 grey40 grey50 grey60 grey70 \
grey grey80 grey90 grey100 light-red light-green light-blue light-magenta light-cyan light-goldenrod \
light-pink light-turquoise gold green dark-green spring-green forest-green sea-green blue dark-blue \
midnight-blue navy medium-blue skyblue cyan magenta dark-turquoise dark-pink coral light-coral \
orange-red salmon dark-salmon khaki dark-khaki dark-goldenrod beige olive orange violet \
dark-violet plum dark-plum dark-olivegreen orangered4 brown4 sienna4 orchid4 mediumpurple3 slateblue1 \
yellow4 sienna1 tan1 sandybrown light-salmon pink khaki1 lemonchiffon bisque honeydew \
slategrey seagreen antiquewhite chartreuse greenyellow gray light-gray light-grey dark-gray slategray \
gray0 gray10 gray20 gray30 gray40 gray50 gray60 gray70 gray80 gray90 \
gray100'

ColorValues = '\
0xffffff 0x000000 0xa0a0a0 0xff0000 0x00c000 0x0080ff 0xc000ff 0x00eeee 0xc04000 0xc8c800 \
0x4169e1 0xffc020 0x008040 0xc080ff 0x306080 0x8b0000 0x408000 0xff80ff 0x7fffd4 0xa52a2a \
0xffff00 0x40e0d0 0x000000 0x1a1a1a 0x333333 0x4d4d4d 0x666666 0x7f7f7f 0x999999 0xb3b3b3 \
0xc0c0c0 0xcccccc 0xe5e5e5 0xffffff 0xf03232 0x90ee90 0xadd8e6 0xf055f0 0xe0ffff 0xeedd82 \
0xffb6c1 0xafeeee 0xffd700 0x00ff00 0x006400 0x00ff7f 0x228b22 0x2e8b57 0x0000ff 0x00008b \
0x191970 0x000080 0x0000cd 0x87ceeb 0x00ffff 0xff00ff 0x00ced1 0xff1493 0xff7f50 0xf08080 \
0xff4500 0xfa8072 0xe9967a 0xf0e68c 0xbdb76b 0xb8860b 0xf5f5dc 0xa08020 0xffa500 0xee82ee \
0x9400d3 0xdda0dd 0x905040 0x556b2f 0x801400 0x801414 0x804014 0x804080 0x8060c0 0x8060ff \
0x808000 0xff8040 0xffa040 0xffa060 0xffa070 0xffc0c0 0xffff80 0xffffc0 0xcdb79e 0xf0fff0 \
0xa0b6cd 0xc1ffc1 0xcdc0b0 0x7cff40 0xa0ff20 0xbebebe 0xd3d3d3 0xd3d3d3 0xa0a0a0 0xa0b6cd \
0x000000 0x1a1a1a 0x333333 0x4d4d4d 0x666666 0x7f7f7f 0x999999 0xb3b3b3 0xcccccc 0xe5e5e5 \
0xffffff'

# get R,G,B components
R(Color) = (Color & 0xff0000)/0x10000
G(Color) = (Color & 0x00ff00)/0x100
B(Color) = (Color & 0xff)
   
PosX(i) = int(i)%10
PosY(i) = floor(i/10.)*10
ColorName(i) = word(ColorNames,int(i))
ColorValue(i) = int(word(ColorValues,int(i)))
ColorValueLabel(i) = sprintf('#%06x',ColorValue(i))
# "empirical" formula do decide whether using a white or a black label on the colored background
ColorLabelColor(c) = (R(c) + G(c)*1.5 + B(c)*0.5)/3. > 127 ? 0x000000 : 0xffffff

set title "Predefined colors in gnuplot" font ",18"
set xrange[-0.5:9.5]
set x2range[-0.5:9.5]
set xtics 1
set x2tics 1
set yrange[119:-5]
set y2range[119:-5]
set ytics 10
set y2tics 10

set style fill solid 1.0 border lc rgb "black"
set samples 111
unset key

plot '+' u (c=$0+1,PosX(c)):(PosY(c)):(0.4):(2.5):(ColorValue(c)) w boxxy lc rgb var, \
     '+' u (c=$0+1,PosX(c)):(PosY(c)+4.2):(ColorName(c)) w labels, \
     '+' u (c=$0+1,PosX(c)):(PosY(c)):(ColorValueLabel(c)):(ColorLabelColor(ColorValue(c))) \
         w labels tc rgb var font "Courier Bold,10"
### end of code

结果:

enter image description here


3

我很惊讶这些方法居然有用!

从文件中读取颜色信息的预期方法是:

plot foo using 1:2:3 lc rgb variable

例如,可以查看在线演示rgb_variable.dem,它从数据文件rgb_variable.dat中读取颜色。但前提是第三列包含十六进制的RGB(或ARGB)值,而不是一个颜色名称的英文单词。Gnuplot所认可的颜色单词名称是内置于名称-> RGB映射中的子集,这些映射曾经在系统文件X11 / rgb.txt中被普遍提供。参见 维基百科X11颜色。该列表的变体成为SVG标准的一部分。将其包含在Gnuplot中旨在用于交互式命令,而不是作为数据文件内容。当然,可以使用Gnuplot数组和用户函数编写扩展的名称-> RGB映射的脚本。例如:
$Data <<EOD
1   40  orange
2   35  cyan
3   25  red
4   15  yellow
5   5   green
EOD

array colorname  = ["orange", "cyan", "red", "yellow", "green"]
array colorvalue = [0xFFD700, 0x00DDDD, 0xDD0000, 0xFFFF00, 0x00DD00]
N = |colorname|
name2RGB(name) = sum [i=1:N] (name eq colorname[i] ? colorvalue[i] : 0) 

set yrange [0:]
set boxwidth 0.7
set style fill solid 1.0
unset key

plot $Data u 1:2:(name2RGB(strcol(3))) w boxes fc rgb variable

在这里输入图片描述

如果您经常处理此类文件内容,我建议您可以自动将整个SVG或X11颜色名称表转换为一对gnuplot数组,并从您的~/.gnuplot初始化加载它。


实际上,为什么在“using”部分定义的变量不能在“with”部分重复使用呢? 例如plot '+' using 0:(i=$1) with p lc iplot $Data using 1:(myColor=strcol(3),$2) with p lc rgb myColor。虽然plot DATA using x:y:pointsize:pointtype:color with points lc variable pt variable ps variable朝着这个方向发展,但不幸的是对于字符串变量并不适用。 - theozh
有几个原因,其中最基本的是,“with <foo>”每个图仅被计算一次,而“using…”则会针对数据集中的每个点重新计算。 - Ethan
好的,我明白了。with <foo> 只在每个图中被评估一次,除非它是 with <property> variable,然而,它只接受数值类型的值。 - theozh
1
每个图表只会对“with <foo>”进行一次评估,没有例外。如果该评估包括一个带有关键字“variable”的属性,则设置一个标志,以便在数据输入期间填充所需的数据值。该机制对数字和字符串值之间没有特殊限制,但到目前为止,接受“variable”的属性通常需要数字而不是字符串。唯一期望字符串输入(“with labels”)的绘图样式不需要“variable”关键字,因为它总是这样运作。 - Ethan
1
2020年新增:gnuplot 5.5提供了一个函数rgbcolor("colorname"),它提供了缺失的步骤。plot FOO using 1:2:(rgbcolor(stringcolumn(3))) lc rgb variable - Ethan
显示剩余2条评论

1
这里有另一种方法,可以使用数据文件或数据块生成自动调色板。使用此方法,您不必关心十六进制数字或任何颜色的编号或代码。您只需要确保不使用无效的颜色名称。对于长数据集,除非存在颜色调色板长度的限制,否则应该可以正常工作。
### colornames from data
reset session

$Data <<EOD
1   40  red
2   35  orange
3   25  yellow
4   20  greenyellow
5   15  web-green
6   12  web-blue
7   10  violet
EOD

MyPalette = '('
set table $Dummy
    plot $Data u (MyPalette = MyPalette.sprintf('%d "%s", ',$0,strcol(3))) with table
unset table
MyPalette = MyPalette[:strlen(MyPalette)-2].')'
set palette model RGB defined @MyPalette
unset colorbox 

set yrange[0:]
plot $Data u 1:2:(0.7):0 w boxes fs solid 1.0 lc palette notitle,\
    '' u 1:($2/2):(strcol(3)) with labels notitle
### end of code

enter image description here


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