Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gnuplot: apply colornames from datafile

Tags:

colors

gnuplot

How can I take colornames from a datafile? I didn't expect this to be so difficult, but apparently it is. Why do version 1 and version 2 give wrong colors? Is there a simpler way to achieve correct colors without using arrays as in version 3? And ...lc var only works with index values but not with colornames.

### 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

like image 466
theozh Avatar asked Feb 12 '19 21:02

theozh


2 Answers

Here is another approach by using an autmatically generated palette from your datafile or datablock. With this you don't have to care about the Hex-numbers or any number or codes of colors. You only need to make sure that you are not using invalid color names. This should work unless there is a limitation on the length of the color palette for long datasets.

### 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

like image 135
theozh Avatar answered Nov 17 '22 19:11

theozh


I'm amazed that any of those methods work at all!

The intended method of reading color information from a file is

plot foo using 1:2:3 lc rgb variable

See for example the online demo rgb_variable.dem that reads colors from data file rgb_variable.dat.

However that assumes column 3 contains a hexadecimal RGB (or ARGB) value, not an English word that is a color name. The color word names recognized by gnuplot are a built-in subset of the name->RGB mapping that used to be universally provided for X11 in a system file X11/rgb.txt. See Wikipedia X11 colors. A variant of this list became part of the SVG standard. The inclusion in gnuplot was intended for use in interactive commands, not as data file content.

It is of course possible to script an expanded name->RGB mapping using gnuplot arrays and user functions. For example:

$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

enter image description here

If you deal with such file content often, I suppose you could automate conversion of the entire SVG or X11 color name tables into such a pair of gnuplot arrays and load that from your ~/.gnuplot initialization.

like image 35
Ethan Avatar answered Nov 17 '22 20:11

Ethan