1

gnuplot 5.x now supports arrays, but there seems to be no way to plot, or fit, to an irregularly-spaced set of data, if it is not provided in an external file. What I would like to see is the ability to plot "y vs x":

array z[8]=[0,1,2,3,4,5,6,6.4]
array f[8]=[0.468,0.405,0.342,0.279,0.216,0.153,0.090,0.064]
plot z,f

or even

plot [3,3],[0,0.25] w lines

which would, for example, provide a handy vertical marker line at x=3 without needing to resort to arrows without heads:

plot '+' using (3):(0):(0):(0.25) with vectors nohead

One can achieve the plotting in this awkward-looking way:

plot sample [j=1:|x|] '+' using (x[j]):(y[j])

but, unfortunately, the same syntax is not recognized by the fit command.

The only way I figured so far is to write the data to a virtual file (a data block), and use it as input to both plot and fit commands:

set print $DATA
print sprintf("# z\tf")    ## header line, overwrite old content if any
set print $DATA append     ## append data lines
do for [j=1:|z|] {
  print sprintf("%f\t%f",z[j],f[j])
  }
unset print

y(x)=m*x-y0
y0=0.25
m=1
fit y(x) $DATA via m,y0
plot $DATA t 'data',y(x) w lines t 'fit'

Is there a better way? Or can someone explain to me why such an obvious task is not a part of the standard plot/array implementation? It certainly would be one of the first things on my wish list.

1
  • Perhaps, another way to think of what I am after is set xrange [0,1,2,3,4,5,6,6.4], or array z[8]=[0,1,2,3,4,5,6,6.4] / set dummy z, or set xrange z. Commented Oct 10, 2017 at 14:06

3 Answers 3

1

What describe is exactly the purpose of data blocks:

$DATA <<EOD
0 0.468
1 0.405
2 0.342
3 0.279
4 0.216
5 0.153
6 0.090
6.4 0.064
EOD

y(x)=m*x-y0
y0=0.25
m=1
fit y(x) $DATA via m,y0
plot $DATA t 'data',y(x) w lines t 'fit'
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks, that's a more compact form for $DATA entry than I had. I guess the advantage of using a sprintf() loop would be an ability to process/format data before plot/fit.
Thanks, Christoph. Some multi-step or iterative calculations might be a tad difficult to read if implemented on the fly, with "using", and clarity can be helpful. My point is more fundamental: why is it that the x array is assumed to always have uniform spacing for functions, while the data arrays are allowed to have x,y pairs, however spaced in x.
Strange, but $DATA <<EOD etc does not work under a Jupyter notebook running a gnuplot kernel extension, while works fine directly in gnuplot. The sprintf() loop works identically in both.
I experimented a bit with arrays: you can plot an array A as plot A. But in general the coma indicates a new plot, plot x, x**2 plots two function. How should gnuplot distinguish for plot array1, array2 between plotting two arrays and plotting array2 vs array1? For parametric mode you must specify exactly two functions to avoid such a confusion, set parametric; plot t,t**2
Perhaps I am not being clear. I am looking for the same way of doing things in plot ... and fit ... commands. With the introduction of arrays in 5.x, there is an implied opportunity to use array z[4] = [1,2.4,3.2,5.0] and then plot y(z) and fit y(z)=... via ... As it stands, I can only do that if I create a data block first, but not directly: functions only work on dummy variables and not on defined arrays. As I said in the original post, one can use plot sample ... '+' but cannot fit sample ... '+', at least as far as I can tell.
|
0

Thanks Christoph for extensive help. It has emerged that data block syntax together with the appropriate "using" options would achieve what I had set out to do. Inline specification for a data block is perfectly compact, and the pre-processing can be replaced for both plot... and fit... with identical syntax:

$DATA <<EOD
0 0.468
1 0.405
2 0.342
3 0.279
4 0.216
5 0.153
6 0.090
6.4 0.064
EOD

y(x)=m*(x-x0)**2+y0
y0=0.9
m=-0.1
x0=4
fit y(x) $DATA using ($1):($1)*($2) via m,x0,y0
plot     $DATA using ($1):($1)*($2) t 'data',y(x) w lines t 'fit'

Comments

0

To plot the data stored in arrays as it is, you can write it in the following way (I tried this in version 5.4).

array z[8]=[0,1,2,3,4,5,6,6.4]
array f[8]=[0.468,0.405,0.342,0.279,0.216,0.153,0.090,0.064]

plot z using (z[$0+1]):(f[$0+1]) 

At first glance, it seems that (z[$0+1]) in using can be replaced by 1, but in the version I tried, I had to do this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.