MPEI_stud
MPEI_stud

Reputation: 123

gnuplot: rotate line title and set offset

I'm trying to plot hs-diagram from csv files.

To plot lines I use

plot 'it175.csv' using 7:6 with lines lc rgb 'green' title '175K' at begin, \
'ib50.csv' using 7:6 with lines lc rgb 'red' title '50MPa' at end

It gives nice isotherm titles,

enter image description here

but worse isobaric

enter image description here

How can I rotate line titles and set offset to the end of the line using 'title "title" at end' without using labels, because there are over 430 lines, and it is very difficult to adjust label coordinates for each line by hand

Upvotes: 1

Views: 327

Answers (1)

theozh
theozh

Reputation: 25843

Let me summarize: you want to print the key/legend/title at the end of the curve rotated by a suitable angle.

If you check help plot title and although it is linked to help key for further parameters, I couldn't find any statement about rotated keys (gnuplot 5.4.1). So, it looks like you have to rotate them yourself, at least, with some effort you can do it automatically.

  • there is the plotting style with labels which has variable rotation (check help labels)
  • the rotation angle of the text should be equal to the angle of the last segment of the curve
  • you need to determine the angle of the last segment of each curve, however, you cannot simply take the coordinates of your plot, but you need to take the "pixel coordinates" of the screen to get the proper "visual" angle.

What the following script does:

  • generates input files for illustration, like your files which contain the value of the labels already in the filename
  • get a list of all files obeying a certain pattern, e.g. it*.dat
  • create a "preliminary" plot in order to get the relationships between plot coordinates and pixel coordinates via the gnuplot variables GPVAL_... which you only get after plotting.
  • plot your data again with lines and labels and at the same time extract the "visual" angle of the last segment of each curve and rotate the label (key/title) accordingly.

I hope you can follow the script below and adapt it to your data. If you need more explanations, let me know. Maybe there is a simpler solution which I am currently not aware of.

Script:

### rotate title at end of curve
reset session

# create some test data files
do for [t=0:5] {
    set print sprintf("it%d.dat",t*5+370)
        do for [x=0:100:5] {
            print sprintf("%g %g",x,(t/3.+0.2)*x**2+t*2000)
        }
    set print
}
do for [t=0:6] {
    set print sprintf("ib%d.dat",t*5+20)
        do for [x=0:100:5] {
            print sprintf("%g %g",x*(t+1)/10.,x**3/35.)
        }
    set print
}

# get a file list

GetFileList(path,expr) = GPVAL_SYSNAME[1:7] eq "Windows" ? \
                         sprintf('dir /b "%s%s"', path, expr) : \
                         sprintf('ls "%s%s"',     path, expr)     # Linux/MacOS
FILES_it = system(GetFileList('','it*.dat'))
FILES_ib = system(GetFileList('','ib*.dat'))

set key noautotitle
set offset 0, graph 0.05, graph 0.05, 0

# plot to get the GPVAL_ ... values
plot for [FILE in FILES_it] FILE u 1:2 w l lc "red", \
     for [FILE in FILES_ib] FILE u 1:2 w l lc "green"

# store GPVAL parameters after plot in variables
txmin = GPVAL_TERM_XMIN; txmax = GPVAL_TERM_XMAX; tymin = GPVAL_TERM_YMIN; tymax = GPVAL_TERM_YMAX
xmin  = GPVAL_X_MIN;     xmax  = GPVAL_X_MAX;     ymin  = GPVAL_Y_MIN;     ymax  = GPVAL_Y_MAX

# x,y to pix and pix to x,y coordinate conversion
XtoPix(x)    = txmin + real(x-xmin)    *(txmax-txmin)/( xmax- xmin)
YtoPix(y)    = tymin + real(y-ymin)    *(tymax-tymin)/( ymax- ymin)

# angle from -180° to +180°
set angle degrees
Angle(x0,y0,x1,y1) = (_dx=x1-x0, _dy=y1-y0, _L=sqrt(_dx**2 + _dy**2), _L==0 ? NaN : \
                     (_dy>=0 ? acos(_dx/_L) : -acos(_dx/_L) ))
# angle for screen coordinates
AngleScr(x0,y0,x1,y1) = Angle(XtoPix(x0),YtoPix(y0),XtoPix(x1),YtoPix(y1))

myLabel(fname,unit) = sprintf(" %s %s",fname[3:strstrt(fname,'.')-1],unit)   # extract number from filename

plot for [FILE in FILES_it] FILE u (last=$0,$1):2 w l lc "red", \
     for [FILE in FILES_it] x1=y1=NaN FILE u (x0=x1,x1=$1,$0==1?x1:NaN):(y0=y1,y1=$2,$0==1?y1:NaN):\
         (myLabel(FILE,"K")):(AngleScr(x0,y0,x1,y1)) every ::last-1::last w labels rotate var left font ",11", \
     for [FILE in FILES_ib] FILE u (last=$0,$1):2 w l lc "green", \
     for [FILE in FILES_ib] x1=y1=NaN FILE u (x0=x1,x1=$1,$0==1?x1:NaN):(y0=y1,y1=$2,$0==1?y1:NaN):\
         (myLabel(FILE,"MPa")):(AngleScr(x0,y0,x1,y1)) every ::last-1::last w labels rotate var left font ",11"
### end of script

Result:

enter image description here

Upvotes: 2

Related Questions