asylumax
asylumax

Reputation: 845

gnuplot 6.02 labels as a function of value

A simple gnuplot to generate labels as function of a particular column is here; also, is a function that can input a value and return a string:

set datafile separator "," 
set datafile commentschar '#'
set key autotitle columnhead # use the first line as title for data
set key noenhanced

function $labellookup(x) << EOF
    temp="null"
    if(x==2000){
    temp="two"
    }
    if(x==1000){
    temp="one"
    }
    if(x==3000){
    temp="three"}
    return temp
EOF

set yrange[*:*]

$DATA << EOD

t, v1, v2
0, 10, 3000
10, 11, 1000
15, 10, 4000
30, 11, 5000
38, 20, 6000
46, 11, 8000
47, 30, 1000
48, 31, 1000
49, 30, 4000
50, 31, 6000
51, 30, 9000
52, 30, 2000
61, 21, 3000
65, 20, 3000
70, 21, 4000
75, 10, 5000

EOD

# use column 1, and column 3 is the label; values
# are (x,y)=(column1, 2)
# column 2 is ignored

plot $DATA using 1:(2):3 with labels rotate by 90 left

When the above is run, the third column is the label as shown. How can the function be used to set the labels as the defined strings, so (for example) instead of seeing "3000" we see "three" in the plot?

enter image description here

Upvotes: 1

Views: 42

Answers (1)

theozh
theozh

Reputation: 26123

If you can directly calculate from your input number the index of a lookup list (as in your case), you can simply do it like the example below. If you have more arbitrary input and output you need to do it differently.

Script: (requires gnuplot>=5.2.0)

### lookup with (index)numbers as input
reset session

$Lookup <<EOD
1000   one
2000   two
3000   three
4000   four
5000   five
6000   six
7000   seven
8000   eight
9000   nine
EOD

$Data <<EOD
10   3.0   9000
20   2.0   7000
30   1.0   3000
40   3.0   1000
50   4.0   4000
60   7.0   5000
70   6.0   6000
80   5.0   8000
90   6.0   2000
EOD

number2text(col) = word($Lookup[int(column(col)/1000)],2)
set offset graph 0.1, graph 0.1, graph 0.1, graph 0.1
set key noautotitle

plot $Data u 1:2 w p pt 7 lc "red", \
        '' u 1:2:(number2text(3)) w labels left offset 0,0.5 rotate by 90
### end of script

Result:

enter image description here

Addition:

If you have an arbitrary string input and want an arbitrary string output you could (mis)use the sum() function as lookup-function. Check the example below where English numbers are translated into French numbers. If a string is not present in your $Lookup, ??? is returned. It's not the most efficient, but for a small number of lookup entries it's good enough.

Maybe gnuplot 6.x with its function blocks (as you have been using) are more efficient. Although, I find providing the lookup data in a simple table (i.e. datablock $Lookup) more convenient than defining dozens of if-clauses.

Script: (requires gnuplot>=5.2.0)

### lookup/dictionary with string input
reset session

$Lookup <<EOD
one      un
two      deux
three    trois
four     quatre
five     cinq
six      six
seven    sept
eight    huit
nine     neuf
EOD

$Data <<EOD
10   3.0   nine
20   2.0   seven
30   1.0   three
40   3.0   one
50   4.0   four
60   7.0   five
70   6.0   six
80   5.0   eight
90   6.0   thousand
EOD

translate(col) = (s='???', sum [i=1:|$Lookup|] \
                 (strcol(col) eq word($Lookup[i],1) ? s=word($Lookup[i],2) : 0, 0), s)
set offset graph 0.1, graph 0.1, graph 0.1, graph 0.1
set key noautotitle

plot $Data u 1:2 w p pt 7 lc "red", \
        '' u 1:2:(translate(3)) w labels left offset 0,0.5 rotate by 90
### end of script

Result:

enter image description here

Upvotes: 1

Related Questions