开发者

Reordering gnuplot key entries

Is there a way to change the order of the entries in the key/legend of gnuplot WITHOUT changing 开发者_高级运维the plot command? (I do not mean reversing the entries)

I have multiple lines in one graph and the graphs are automatically generated for a wide range of different input data. I want to have the key entries sorted by their value on the far left of the graph. Changing the plot command is not possible, because this would have to be done for each graph individually.


As stated HERE, the key can only be reversed with

set key reverse

Unfortunately, AFAIK a reordering of the key is not possible.


It is possible. What I do is this: The first half of my plot command are the normal plot commands for the lines I want to have in the order I want them. But with the option 'notitle' on each line. The second half of my plot command plot basically empty lines, but with titles in the order I want them to show in the key, of course with the same styles as the plotted lines.

Example code:

    DataFile using 1:4 notitle with lines ls 3,\
    '' using 1:2 notitle with lines ls 1,\
    '' using 1:3 notitle with lines ls 2,\
    EmptyFile title "One" with lines ls 1,\
    '' title "Two" with lines ls 2,\
    '' title "Three" with lines ls 3

Can't remember atm if my EmptyFile contains nothing or just a set of data that is definitely outside my graph area.


As I understand the question: How to rearrange the legend entries depending on data? Of course, you can always rearrange the legend entries manually as in @terter's answer, but I guess this was not OP's request.

Actually, when I was "fighting" for a solution (especially for older gnuplot versions), I was implying the order of the data on the far right (where the legend is), but reading the question again, the OP was asling on the left side. I'm sure it can also be changed (if requested by OP or anybody else).

Unfortunately, if you want to sort something in gnuplot you are supposed to use external tools which might make it platform-dependent. Hence, for Script2 and Script3, I implemented the (inefficient) bubble-sort (mis)using the function sum (check help sum). For this small amount of data, I would say it's still justifiable.

Script 1: (works for gnuplot>=4.4.0, March 2010)

The script generates data on the fly.

gnuplot 4.4.0 does not have sum and stats which makes it a bit difficult. Futhermore, gnuplot has no internal sorting feature. So, here, sorting is realized by comparing tokens in a string and potentially swapping places. This is done only for 3 tokens, more entries might get pretty lengthy.

### rearrange the legend entries depending on data
reset

Vs = Ts = ''
Ns = "1 2 3"
v(i)  = real(word(Vs,i))
n(i)  =  int(word(Ns,i))
t(i)  =      word(Ts,i)
 
getKeyParams(s,v) = (Ts=Ts.sprintf(" %s",s), Vs=Vs.sprintf(" %g",v))

Sort3(s) = (v(1)<v(2) ? (Vs=sprintf("%g %g %g",v(2),v(1),v(3)), Ns=sprintf("%d %d %d",n(2),n(1),n(3))) : 0, \
            v(2)<v(3) ? (Vs=sprintf("%g %g %g",v(1),v(3),v(2)), Ns=sprintf("%d %d %d",n(1),n(3),n(2))) : 0, \
            v(1)<v(2) ? (Vs=sprintf("%g %g %g",v(2),v(1),v(3)), Ns=sprintf("%d %d %d",n(2),n(1),n(3))) : 0)

set key out noautotitle
set xrange[0:]

set multiplot layout 3,1
    y0 = 100
    plot '+' u 0:(y0=y0+rand(0)-0.5) w l, tmp=getKeyParams("DataA",y0), \
         '+' u 0:(y0=y0+rand(0)-0.5) w l, tmp=getKeyParams("DataB",y0), \
         '+' u 0:(y0=y0+rand(0)-0.5) w l, tmp=getKeyParams("DataC",y0), \
         tmp=Sort3(0) '+' u (NaN) noautoscale, \
         for [i=1:words(Ts)] '+' u 0:(NaN) every ::::words(Ts)-1 noautoscale w l ls n(i) ti t(n(i))

    Vs = Ts = ''
    Ns = "1 2 3"
    replot

    Vs = Ts = ''
    Ns = "1 2 3"
    replot
 
unset multiplot
### end of script

Result 1: (created with gnuplot 4.4.0)

Reordering gnuplot key entries

Data: SO6290504.dat

X Data1 Data2 Data3 Data4 Data5 Data6 Data7 Data8
0  96.4  93.3  99.5  97.3  95.9  91.9  98.9  98.0
1  96.1  93.2  99.5  97.6  96.0  91.9  98.7  98.4
2  96.0  93.1  99.3  97.7  95.7  91.5  99.2  98.2
3  96.5  92.8  99.2  97.8  96.1  92.0  99.2  98.3
4  96.7  92.3  99.0  97.4  95.7  91.8  99.0  97.9
5  96.3  92.3  99.4  97.5  95.7  92.3  98.7  98.2
6  95.9  92.7  99.4  97.4  96.0  91.9  99.1  98.7
7  95.8  92.4  99.2  97.0  96.4  91.6  99.5  98.5

Script 2: (works for gnuplot>=4.6.0, March 2012)

Although gnuplot4.6.0 has stats it doesn't have the variable STATS_columns. So, you have to count the columns differently. How to check for gnuplot 4.x and 5.x? tm_wday(0) is 6 for gnuplot4.x and 4 for gnuplot5.x, check help time and help tm_wday. gnuplot4.6.0 doesn't have datablocks and writing to file is a bit painful, hence the data is provided by a datafile.

### rearrange the legend entries depending on data
reset

FILE = "SO6290504.dat"

if (tm_wday(0)==6) {     # check if gnuplot 4.x
    set datafile separator "\t"
    stats FILE u (NCols=words(strcol(1))) nooutput
    set datafile separator whitespace   # reset to default
} 
else {
    stats FILE u 0 nooutput
    NCols = int(STATS_columns)
}

v(i) = real(word(Vs,i))
n(i) =  int(word(Ns,i))
t(i) =      word(T0,i)

Swap(s,i1,i2) = (_s='', sum [_i=1:i1-1] (_s=_s.' '.word(s,_i),0),    _s = _s.' '.word(s,i2), \
                        sum [_i=i1+1:i2-1] (_s=_s.' '.word(s,_i),0), _s = _s.' '.word(s,i1), \
                        sum [_i=i2+1:words(s)] (_s=_s.' '.word(s,_i),0), _s)

Sort(N,V) = (Ns=N, Vs=V, sum[_j=1:words(V)] ( sum[_k=1:words(V)-_j] ( tmp = v(_k)<v(_k+1) ? \
             (Ns=Swap(Ns,_k,_k+1), Vs=Swap(Vs,_k,_k+1)) : 0, 0), 0), Ns)

getKeyParams(col) = (N0=V0='', (sum [_i=2:NCols] ( \
                     N0=N0.sprintf(" %d",_i-1), \
                     V0=V0.sprintf(" %g",column(_i)),0)), column(col))

set key out noautotitle

plot for [col=2:NCols] FILE u 1:(getKeyParams(col)):(col-1) w l lc var lw 2, \
     tmp = Sort(N0,V0) '+' u (NaN):(NaN) every ::0::0, \
     for [col=2:NCols] FILE u 1:(NaN) w l lc n(col-1) lw 2 ti columnhead(n(col-1)+1)
### end of script

Result 2: (created with gnuplot 4.6.0)

Reordering gnuplot key entries

Script 3: (works for gnuplot>=5.2.2, Nov. 2017)

gnuplot5.2.0 offers arrays which makes things a lot easier. Although, so far, I could not get a working script for 5.2.0 because of some issues with columnhead.

### rearrange the legend entries depending on data
reset session

FILE = "SO6290504.dat"

stats FILE u 0 nooutput
NCols = int(STATS_columns)
array N[NCols-1]
array V[NCols-1]
array T[NCols-1]

Swap(i1,i2) = (_tmp=N[i1], N[i1]=N[i2], N[i2]=_tmp, \
               _tmp=V[i1], V[i1]=V[i2], V[i2]=_tmp, \
               _tmp=T[i1], T[i1]=T[i2], T[i2]=_tmp)

Sort(n) = (sum[_j=1:|V|] ( sum[_k=1:|V|-_j] ( tmp = V[_k]<V[_k+1] ? \
           tmp=Swap(_k,_k+1) : 0, 0)))

getKeyParams(col) = (N[col-1]=col-1, T[col-1]=columnhead(col), V[col-1]=column(col))

set key out noautotitle

plot for [col=2:NCols] FILE u 1:(getKeyParams(col)):(col-1) w l lc var lw 2, \
     tmp = Sort(0) '+' u (NaN) every ::0::0, \
     for [i=1:|N|] '+' u (NaN) every ::0::0 w l lc N[i] lw 2 ti T[i]
### end of script

Result 3: (created with gnuplot5.2.2)

Reordering gnuplot key entries

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜