petrosca
petrosca

Reputation: 45

gnuplot: Is there a way to plot vertical lines spatially?

I am trying to plot several vertical lines of a variable, say velocity (m/s), against a x-axis of distance (m) and a y-axis of height(m). Each of the velocity profiles come as a function of height measured at different locations. So the aim is to observe how these profiles change spatially.

I have thought to approach this by shifting the vertical profiles by the x-component corresponding to the location where each profile was measured. So if we suppose that the second x-axis depicts velocity I want it to reset to 0 at every point of measurement.

Sketch of desired outcome (ignoring black colour): enter image description here

Does anyone have any idea of what the right course of action would be? I am using gnuplot but any alternatives are welcome. Thanks in advance.

EDIT:

Below you may have a look at the data I use (file verProfiles in the code snippet)

z(m) U_1(m/s)* U_4(m/s)* U_8(m/s)*
0.50 1.66 1.82 1.95
0.75 1.85 2.04 2.11
1.00 2.00 2.20 2.18
1.25 2.12 2.34 2.21
1.50 2.23 2.36 2.22
1.75 2.33 2.37 2.22
2.00 2.41 2.38 2.22

*The numbers 1, 4 and 8 in the names of U variables in the table above denote the location where the measurements are taken hence each U profile should start and the respective x point in the graph.

The gnuplot code that I've written so far and generates a false graph is:

outName="U_test.png"

set terminal pngcairo font "helvetica,20" size 800, 1000
set xtics nomirror
set x2tics
set xrange [0:10] noreverse nowriteback
set autoscale x2fix
set yrange [0:2.5]
set grid
set mxtics 4
set mx2tics 4
set mytics 4
set key left top
set key samplen 2
set key spacing 0.75
set xlabel  "x"
set x2label "Ux [m s^{-1}]"
set ylabel "z"
set output "$outName"

inp0="verProfiles"

plot \
    inp0 u 2:1 t "U_1" axes x2y1 w lp ps 2 lw 2 lc rgb "#009E73", \
    inp0 u 3:1 t "U_4" axes x2y1 w lp ps 2 lw 2 lc rgb "#3F8B77", \
    inp0 u 4:1 t "U_8" axes x2y1 w lp ps 2 lw 2 lc rgb "#7EA99E"

The generated false graph is:

enter image description here

Upvotes: 2

Views: 727

Answers (1)

theozh
theozh

Reputation: 25714

Assuming I've understood your intention correctly, this would be my suggestion. You want to offset your x-data by 1,4, and 8, so you have to add these values to your columns $2, $3, $4. If I understood your sketch with 0 m/s correctly, you also want to subtract the first velocity value from it. Please correct me if I'm wrong. So, you take the pseudocolumn 0 (check help pseudocolumns), which is basically the line number starting from 0. If $0==0 (check ternary operator help ternary) you assign the current value (only the first value) of your column to a variable, e.g. xoff=$2and subtract it from all following values in your column. Since you have a header you have to skip one line, i.e. skip 1.

In case you want several x-axes on top all starting from 0, this could be either done with arrows and labels or depending on what exactly you need maybe with multiplots (check help multiplot).

Check the following as starting point:

Code:

### plotting with different offsets
reset session

$Data <<EOD
z(m)  U_1(m/s)*  U_4(m/s)*  U_8(m/s)*
0.50       1.66       1.82       1.95
0.75       1.85       2.04       2.11
1.00       2.00       2.20       2.18
1.25       2.12       2.34       2.21
1.50       2.23       2.36       2.22
1.75       2.33       2.37       2.22
2.00       2.41       2.38       2.22
EOD

set xrange[0:10]
set xtics 1
set yrange [0.3:2.4]
set grid xtics, ytics

vs = "1 4 8"
set for [v in vs] arrow from v, graph 0 to v, graph 1 lw 1.5 lc "black" dt 2 nohead

plot $Data u ($0==0?xoff=$2:0, $2+1-xoff):1 skip 1 w lp ps 1.5 lw 2 pt 7 lc "red"   ti "U_1", \
     ''    u ($0==0?xoff=$3:0, $3+4-xoff):1 skip 1 w lp ps 1.5 lw 2 pt 7 lc "green" ti "U_4", \
     ''    u ($0==0?xoff=$4:0, $4+8-xoff):1 skip 1 w lp ps 1.5 lw 2 pt 7 lc "black" ti "U_8"
### end of code

Result:

enter image description here

Addition:

Maybe now I have a better idea about what you probably want. I guess you "simply" want to have subplots at defined locations within a "Main"plot. gnuplot offers the feature of multiplot (check help multiplot) which will place several plots next to or on top of each other. You can define the origin (check help origin) and the size (check help size) of each subplot. However, the coordinates and sizes of the subplots are given in screen coordinates. The problem is now: how to place the plot at the desired location relative to the first plot? With labels, arrows, and objects you can use screen, graph and axes coordinates (check help coordinates), but I am not aware that you can use axis coordinates of the previous plot. So, you have to calculate these positions yourself using some internal gnuplot variables GPVAL_.... It looks complicated but is just some coordinate transformation.

Code:

### plotting with different offsets
reset session

$Data <<EOD
z(m)  U_1(m/s)*  U_4(m/s)*  U_8(m/s)*
0.50       1.66       1.82       1.95
0.75       1.85       2.04       2.11
1.00       2.00       2.20       2.18
1.25       2.12       2.34       2.21
1.50       2.23       2.36       2.22
1.75       2.33       2.37       2.22
2.00       2.41       2.38       2.22
EOD

set for [v in "1 4 8"] arrow from v, graph 0 to v, graph 1 lw 1.5 lc "black" dt 2 nohead

XFirstToGrphRel(x) = (x-MainXMin)/(MainXMax - MainXMin)   # relative position to graph 
YFirstToGrphRel(y) = (y-MainYMin)/(MainYMax - MainYMin)
PosX(x) = XminScrRel+GraphInScrSizeX*XFirstToGrphRel(x)   # screen positon of the subplot
PosY(y) = YminScrRel+GraphInScrSizeY*YFirstToGrphRel(y)
SizeX(dx) = GraphInScrSizeX*dx/(MainXMax - MainXMin)      # screen size of a subplot 
SizeY(dy) = GraphInScrSizeY*dy/(MainYMax - MainYMin)

set multiplot 

    set xlabel "x / m"
    set xrange[0:12]
    set xtics 1
    set ylabel "z / m"
    set yrange [0.3:2.4]
    set ytics 0.5
    set grid xtics, ytics

    plot 0 w p ps 0 notitle    # plot nothing, just background plot
    # store the current terminal values for later use
    MainXMin = GPVAL_X_MIN
    MainXMax = GPVAL_X_MAX
    MainYMin = GPVAL_Y_MIN
    MainYMax = GPVAL_Y_MAX
    GraphInScrSizeX = real(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)/GPVAL_TERM_XSIZE*GPVAL_TERM_SCALE  # real() to avoid integer division
    GraphInScrSizeY = real(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)/GPVAL_TERM_YSIZE*GPVAL_TERM_SCALE
    XminScrRel = real(GPVAL_TERM_XMIN)/GPVAL_TERM_XSIZE*GPVAL_TERM_SCALE   
    YminScrRel = real(GPVAL_TERM_YMIN)/GPVAL_TERM_YSIZE*GPVAL_TERM_SCALE

    unset arrow
    set margins 0,0,0,0
    unset xlabel
    unset xtics
    set x2label "v / m/s"
    set x2range [0:2.5]
    set x2tics 0.5 offset 0.5
    unset ylabel
    set format y ""
    set yrange [0.5:2.0]
    set grid x2tics, ytics
    
    set object 1 rect from graph 0, graph 0 to graph 1, graph 1 behind fc "white"
    set size SizeX(2),SizeY(1.5)

    set origin PosX(1),PosY(0.5)
    plot $Data u 2:1 axes x2y1 w lp pt 7 lc "red" notitle
    
    set origin PosX(4.0),PosY(0.5)
    plot $Data u 3:1 axes x2y1 w lp pt 7 lc "green" notitle
    
    set origin PosX(8.0),PosY(0.5)
    plot $Data u 4:1 axes x2y1 w lp pt 7 lc "blue" notitle
    
unset multiplot
### end of code

Result:

enter image description here

Upvotes: 1

Related Questions