colorsgnuplot

gnuplot: apply colornames from datafile


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


Solution

  • In case somebody wants to use a lookup table as @Ethan suggested, here are the 111 predefined gnuplot colors taken from the gnuplot console show colors and put into arrays.

    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]
    

    Addition: for what it's worth, just for completeness and illustration... Below some script to generate an overview about the predefined gnuplot colors. Instead of arrays (only available since gnuplot 5.2.0), the colors are listed in a long string (hence the \ at the end of each line) which also can be loaded from a file. This will also work for gnuplot>=4.6.0.

    Data 1: ColorsPredefined.dat

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

    Script 1: (works for gnuplot>=4.6.0, no arrays and bitshift at that time)

    ### display all predefined gnuplot colors (gnuplot>=4.6.0)
    reset
    set term wxt size 1200,700 enhanced   # or change to another terminal
    
    load "ColorsPredefined.dat"         # load color definition string
    
    # get R,G,B components
    r(Color) = (Color & 0xff0000)/0x10000
    g(Color) = (Color & 0x00ff00)/0x100
    b(Color) = (Color & 0xff)
    # "empirical" formula do decide whether using a white or a black label on the colored background
    labelColor(c) = (r(c) + g(c)*1.5 + b(c)*0.5)/3. > 127 ? 0x000000 : 0xffffff
    
    cols          = 10
    rows          = ceil(words(colorsPredefined)*0.5/cols)
    posX(i)       = floor(i/rows)
    posY(i)       = int(i)%rows*rows
    colorName(i)  = word(colorsPredefined,int(2*i+2))
    colorValue(i) = int(word(colorsPredefined,int(2*i+1)))
    labelValue(i) = sprintf('#%06x',colorValue(i))
    
    set title "Predefined colors in gnuplot" font ",18"
    set style fill solid 1.0 border lc rgb "black"
    set samples words(colorsPredefined)/2
    set offsets 0,0,5,0
    set yrange [:] reverse
    unset tics
    unset key
    unset border
    
    plot [-0.5:cols-0.5] '+' u (c=$0,posX(c)):(posY(c)):(0.4):(2.5):(colorValue(c)) w boxxy lc rgb var, \
         '+' u (c=$0,posX(c)):(posY(c)):(colorName(c)) w labels offset 0,-1.5, \
         '+' u (c=$0,posX(c)):(posY(c)):(labelValue(c)):(labelColor(colorValue(c))) \
             w labels tc rgb var font "Courier Bold,12"
    ### end of script
    

    Result 1:

    enter image description here

    Now, let's do it with custom defined colors defined in a simple text file read into a gnuplot datablock. Datablocks can be indexed since gnuplot>=5.2.0, hence, making modifications much easier than modifying a long string or two corresponding arrays, and furthermore, you could add optional comments at the end of each line. A look-up function (mis)using gnuplot's sum function is added as well.

    Data 2: ColorsCustom.dat (color names and values taken from here)

    ### custom colors and function to set color by name
    
    myColor(s) = sum [_i=1:|$myColors|] (s eq word($myColors[_i],2) ? int(word($myColors[_i],1)) : 0 )
    
    $myColors <<EOD
    0xc71585   mediumvioletred         # pink colors
    0xff1493   deeppink
    0xdb7093   palevioletred
    0xff69b4   hotpink
    0xffb6c1   lightpink
    0xffc0cb   pink
    0x8b0000   darkred                 # red colors
    0xff0000   red
    0xb22222   firebrick
    0xdc143c   crimson
    0xcd5c5c   indianred
    0xf08080   lightcoral
    0xfa8072   salmon
    0xe9967a   darksalmon
    0xffa07a   lightsalmon
    0xff4500   orangered               # orange colors
    0xff6347   tomato
    0xff8c00   darkorange
    0xff7f50   coral
    0xffa500   orange
    0xbdb76b   darkkhaki               # yellow colors
    0xffd700   gold
    0xf0e68c   khaki
    0xffdab9   peachpuff
    0xffff00   yellow
    0xeee8aa   palegoldenrod
    0xffe4b5   moccasin
    0xffefd5   papayawhip
    0xfafad2   lightgoldenrodyellow
    0xfffacd   lemonchiffon
    0xffffe0   lightyellow
    0x800000   maroon                  # brown colors
    0xa52a2a   brown
    0x8b4513   saddlebrown
    0xa0522d   sienna
    0xd2691e   chocolate
    0xb8860b   darkgoldenrod
    0xcd853f   peru
    0xbc8f8f   rosybrown
    0xdaa520   goldenrod
    0xf4a460   sandybrown
    0xd2b48c   tan
    0xdeb887   burlywood
    0xf5deb3   wheat
    0xffdead   navajowhite
    0xffe4c4   bisque
    0xffebcd   blanchedalmond
    0xfff8dc   cornsilk
    0x4b0082   indigo                  # purple, violet, and magenta colors
    0x800080   purple
    0x8b008b   darkmagenta
    0x9400d3   darkviolet
    0x483d8b   darkslateblue
    0x8a2be2   blueviolet
    0x9932cc   darkorchid
    0xff00ff   fuchsia
    0xff00ff   magenta
    0x6a5acd   slateblue
    0x7b68ee   mediumslateblue
    0xba55d3   mediumorchid
    0x9370db   mediumpurple
    0xda70d6   orchid
    0xee82ee   violet
    0xdda0dd   plum
    0xd8bfd8   thistle
    0xe6e6fa   lavender
    0x191970   midnightblue            # blue colors
    0x000080   navy
    0x00008b   darkblue
    0x0000cd   mediumblue
    0x0000ff   blue
    0x4169e1   royalblue
    0x4682b4   steelblue
    0x1e90ff   dodgerblue
    0x00bfff   deepskyblue
    0x6495ed   cornflowerblue
    0x87ceeb   skyblue
    0x87cefa   lightskyblue
    0xb0c4de   lightsteelblue
    0xadd8e6   lightblue
    0xb0e0e6   powderblue
    0x008080   teal                    # cyan colors
    0x008b8b   darkcyan
    0x20b2aa   lightseagreen
    0x5f9ea0   cadetblue
    0x00ced1   darkturquoise
    0x48d1cc   mediumturquoise
    0x40e0d0   turquoise
    0x00ffff   aqua
    0x00ffff   cyan
    0x7fffd4   aquamarine
    0xafeeee   paleturquoise
    0xe0ffff   lightcyan
    0x006400   darkgreen               # green colors
    0x008000   green
    0x556b2f   darkolivegreen
    0x228b22   forestgreen
    0x2e8b57   seagreen
    0x808000   olive
    0x6b8e23   olivedrab
    0x3cb371   mediumseagreen
    0x32cd32   limegreen
    0x00ff00   lime
    0x00ff7f   springgreen
    0x00fa9a   mediumspringgreen
    0x8fbc8f   darkseagreen
    0x66cdaa   mediumaquamarine
    0x9acd32   yellowgreen
    0x7cfc00   lawngreen
    0x7fff00   chartreuse
    0x90ee90   lightgreen
    0xadff2f   greenyellow
    0x98fb98   palegreen
    0xffe4e1   mistyrose               # white colors
    0xfaebd7   antiquewhite
    0xfaf0e6   linen
    0xf5f5dc   beige
    0xf5f5f5   whitesmoke
    0xfff0f5   lavenderblush
    0xfdf5e6   oldlace
    0xf0f8ff   aliceblue
    0xfff5ee   seashell
    0xf8f8ff   ghostwhite
    0xf0fff0   honeydew
    0xfffaf0   floralwhite
    0xf0ffff   azure
    0xf5fffa   mintcream
    0xfffafa   snow
    0xfffff0   ivory
    0xffffff   white
    0x000000   black                   # gray and black colors
    0x2f4f4f   darkslategray
    0x696969   dimgray
    0x708090   slategray
    0x808080   gray
    0x778899   lightslategray
    0xa9a9a9   darkgray
    0xc0c0c0   silver
    0xd3d3d3   lightgray
    0xdcdcdc   gainsboro
    EOD
    
    ### end of file
    

    Script 2: (works for gnuplot>=5.2.0)

    # overview about custom colors (gnuplot>=5.2.0)
    reset session
    
    set term wxt size 1200,800    # or any other terminal
    
    load "ColorsCustom.dat"       # custom defined colors & colornames
    
    # get R,G,B components
    r(color) = (color & 0xff0000)/0x10000
    g(color) = (color & 0x00ff00)/0x100
    b(color) = (color & 0xff)
    # "empirical" formula do decide whether using white or black label on colored background
    labelColor(c) = (r(c) + g(c)*1.5 + b(c)*0.5)/3. > 127 ? 0x000000 : 0xffffff
    
    cols          = 10
    rows          = |$myColors|/cols
    posX(i)       = floor(i/rows)
    posY(i)       = int(i)%rows*rows
    colorName(i)  = word($myColors[i+1],2)
    colorValue(i) = int(word($myColors[i+1],1))
    labelValue(i) = sprintf('#%06x',colorValue(i))
    
    set title "Custom defined colors in gnuplot" font ",18"
    set style fill solid 1.0 border lc rgb "black"
    set samples |$myColors|
    set margins 0,0,2,-1
    set yrange reverse
    unset tics
    unset key
    unset border
    
    plot [-0.5:cols-0.5] '+' u (c=$0,posX(c)):(posY(c)):(0.4):(3.5):(colorValue(c)) w boxxy lc rgb var, \
         '+' u (c=$0,posX(c)):(posY(c)):(colorName(c)) w labels offset 0,-1.4, \
         '+' u (c=$0,posX(c)):(posY(c)):(labelValue(c)):(labelColor(colorValue(c))) \
             w labels tc rgb var font "Courier Bold,12"
    ### end of script
    

    Result 2:

    enter image description here

    Now, let's get back to the original question, how can I use (custom) colornames from a column instead the RGB-color code?

    Script 3: (works for gnuplot>=5.2.0)

    ### get colors via colorname from file (gnuplot>=5.2.0)
    reset session
    
    load "ColorsCustom.dat"   # load your own color table and function
    
    $Data <<EOD
    1   40   darkviolet
    2   35   blue
    3   30   aqua
    4   25   lime
    5   20   yellow
    6   15   darkorange
    7   10   tomato
    8    5   red
    9    3   fuchsia
    EOD
    
    set style fill solid 1.0
    set boxwidth 0.8
    set key noautotitle
    
    plot $Data u 1:2:(myColor(strcol(3))) w boxes lc rgb var, \
            '' u 1:($2/2):3 w labels
    ### end of script
    

    Result 3:

    enter image description here