147pm
147pm

Reputation: 2239

Simple line from two points continuing through points

I simply want to draw a line in 2-D from two points, but have the line continue beyond the two points. The following code works if I want a line segment ending at the points, but I'd like the line to continue on through to the edges. Here's what I have that ends at the points

data:
 x  y
 0  4
 1 -1 

reset
set terminal svg enhanced fname 'Times New Roman' rounded dashed standalone
set size ratio 1.0
set xrange[-2:3]
set yrange[-2:6]
set style line 1 \
    linecolor rgb '#0060ad' \
    linetype 1 linewidth 2 \
    pointtype 7 pointsize 1.0
plot data with lp ls 1 

I want it to keep going through, past the defining points to the edges.

Upvotes: 0

Views: 459

Answers (1)

Eldrad
Eldrad

Reputation: 743

There are many ways to obtain a linear function f(x) = a+b*x from two points provided as input data, here are three different ones.

Read (x1,y1,x2,y2) from datablock

One can set up the coordinates as a datablock and use the elements to explicitly calculate a and b. Unfortunately, indexing a datablock is a bit cumbersome in gnuplot, therefore the function definition becomes quite lengthy:

$DATA << EOD
0.0   4.0
1.0  -1.0 
EOD

a(x1,y1,x2,y2) = (y1*x2 - y2*x1) / (x2 - x1)
b(x1,y1,x2,y2) = (y2 - y1) / (x2 - x1)

f(x) = a(word($DATA[1],1), word($DATA[1],2), word($DATA[2],1), word($DATA[2],2)) + \
       b(word($DATA[1],1), word($DATA[1],2), word($DATA[2],1), word($DATA[2],2)) * x

plot $DATA, f(x)

Explanation: $DATA[1] gives the complete first row, word picks the first or second element using the spaces as delimiters. If your data points should be read in from a file mydata.dat, then change the first code block to:

set table $DATA
plot 'mydata.dat' with table
unset table

Sidenote: Writing the numbers as 1.0 instead of 1 circumvents the pitfall of integer calculations.

Read (x1,y1,x2,y2) from arrays

If the x and y values are provided in two separate arrays, indexing becomes easier, and the function definition can be shortened:

array xvals[2] = [0.0, 1.0]
array yvals[2] = [4.0, -1.0]

a(x1,y1,x2,y2) = (y1*x2 - y2*x1) / (x2 - x1)
b(x1,y1,x2,y2) = (y2 - y1) / (x2 - x1)

f(x) = a(xvals[1], yvals[1], xvals[2], yvals[2]) + \
       b(xvals[1], yvals[1], xvals[2], yvals[2]) * x

plot xvals u 2:(yvals[$0+1]) w lp ls 1, f(x)

Or, again, reading from file:

array xvals[2]
array yvals[2]
do for [i=1:2] {
  stats 'mydata.dat' every ::i-1::i-1 using (xvals[i]=$1,yvals[i]=$2) noout
}

Make (trivial) fit

One can perform a (strictly speaking non-linear) fit – of course, gnuplot will complain that the error becomes zero:

f(x) = a + b*x
fit f(x) $DATA via a,b
# fit f(x) 'mydata.dat' via a,b
plot $DATA w lp ls 1, f(x)

enter image description here

Edit: 4th variant using stats

The stats command by default performs a linear fit on any data set it is fed with and create a bunch of STATS_* variables:

stats 'mydata.dat' nooutput
a = STATS_intercept
b = STATS_slope
f(x) = a + b*x
plot 'mydata.dat', f(x)

Upvotes: 1

Related Questions