Fit exception on gnuplot - gnuplot

I try to plot a data with an exponentiel regression :
set terminal postscript enhanced color
set output 'fichier.ps'
set logscale y
set logscale x
set format y "10^{%L}"
set format x "10^{%L}"
set key inside right top
set xlabel " lines "
set ylabel " Time(nanoseconds)"
f(x) = a + b*exp (x)
fit f(x) 'fichier.csv' using 16:17 via a, b
plot 'fichier.csv' using 16:17 with points title "title" lw 3 pt 4 linecolor rgb "#FF0000", f(x) with lines title "regtitle" linecolor rgb "#000000" lw 3
I have this error :
Max. number of data points scaled up to: 3072
Undefined value during function evaluation
and i run on gnuplot 4.4
how to resolve problem ?

The message Max. number of data points scaled up to: 3072 has nothing to do with the fit error, see also Gnuplot : How to set max number of data points for fit
Your fit error likely is due to faulty data or badly set initial values of the parameters. If you don't set the variables at all before the fit, gnuplot initialises them with 1.0, which might be totally off. Exponential fits are notoriously unstable with bad starting values. You might use gnuplots stats command to find out a bit more about your data before fitting.

Related

Gnuplot: oscilloscope-like line style?

Is it possible in Gnuplot to emulate the drawing style of an analogue oscilloscope, meaning thinner+dimmisher lines on larger amplitudes, like this:?
The effect you see in the oscilloscope trace is not due to amplitude, it is due to the rate of change as the trace is drawn. If you know that rate of change and can feed it to gnuplot as a third column of values, then you could use it to modulate the line color as it is drawn:
plot 'data' using 1:2:3 with lines linecolor palette z
I don't know what color palette would work best for your purpose, but here is an approximation using a function with an obvious, known, derivative.
set palette gray
set samples 1000
plot '+' using ($1):(sin($1)):(abs(cos($1))) with lines linecolor palette
For thickness variations, you could shift the curve slightly up and down, and fill the area between them.
f(x) = sin(2*x) * sin(30*x)
dy = 0.02
plot '+' u 1:(f(x)+dy):(f(x)-dy) w filledcurves ls 1 notitle
This does not allow variable colour, but the visual effect is similar.
Another approach:
As #Ethan already stated, the intensity is somehow proportional to the speed of movement, i.e. the derivative. If you have sin(x) as waveform, the derivative is cos(x). But what if you have given data? Then you have to calculate the derivative numerically.
Furthermore, depending on the background the line should fade from white (minimal derivative) to fully transparent (maximum derivative), i.e. you should change the transparency with the derivative.
Code:
### oscilloscope "imitation"
reset session
set term wxt size 500,400 butt # option butt, otherwise you will get overlap points
set size ratio 4./5
set samples 1000
set xrange[-5:5]
# create some test data
f(x) = 1.5*sin(15*x)*(cos(1.4*x)+1.5)
set table $Data
plot '+' u 1:(f($1)) w table
unset table
set xtics axis 1 format ""
set mxtics 5
set grid xtics ls -1
set yrange[-4:4]
set ytics axis 1 format ""
set mytics 5
set grid ytics ls -1
ColorScreen = 0x28a7e0
set obj 1 rect from screen 0,0 to screen 1,1 behind
set obj 1 fill solid 1.0 fc rgb ColorScreen
x0=y0=NaN
Derivative(x,y) = (dx=x-x0,x0=x,x-dx/2,dy=y-y0,y0=y,dy/dx) # approx. derivative
# get min/max derivative
set table $Dummy
plot n=0 $Data u (d=abs(Derivative($1,$2)),n=n+1,n<=2? (dmin=dmax=d) : \
(dmin>d ? dmin=d:dmin), (dmax<d?dmax=d:dmax)) w table
unset table
myColor(x,y) = (int((abs(Derivative(column(x),column(y)))-dmin)/(dmax-dmin)*0xff)<<24) +0xffffff
plot $Data u 1:2:(myColor(1,2)) w l lw 1.5 lc rgb var not
### end of code
Result:

How to make dashed grid lines intersect making crosshairs in gnuplot?

I'm plotting some data and I want to use dashed grid lines.
Any dashed grid line would suffice, but I prefer a "long dash, short dash, long dash" format.
For example, given the following code
set grid lc rgb "#000000" lt 1 dt (50, 25, 20, 25)
plot x**2
I get this result
But I would rather the grid lines intersection to happen always at the middle of two dashes, like this
If I could make horizontal grid lines different to vertical grid lines and I could add some offset to each one, then I'd imagine there's a way to accomplish this. But I can't seem to do that either.
It looks like gnuplot cannot have two different dashstyles for x-grid and y-grid.
One workaround I see currently is to plot two identical plot on top of each other. One with appropriate x-grid lines and the other with appropriate y-grid lines.
If you want a dash pattern with proportions of (50-25-20-25), this correspond to (25-25-20-25-25-0) or (5-5-4-5-5-0) between two tics.
Furthermore, the dash and gap length numbers, e.g. in dt (50,25,20,25), seem to be in a fixed relation to the graph size. The "empirical" factor is 11 with good approximation (at least for the wxt terminal which I tested under gnuplot 5.2.6).
Edit: actually, the code below gives different results with a qt terminal. And it's not just a different factor. It's more complicated and probably difficult to solve without insight into the source code. So, the fact that the following seems to work with wxt terminal (maybe even just under Windows?) was probably a lucky strike.
With this you can create your dash lines automatically resulting in crosshairs at the intersections of the major grid lines.
Assumptions are:
your first and last tics are on the borders
you know the number of x- and y-intervals
You also need to know the graph size. These values are stored in the variables GPVAL_TERM..., but only after plotting. That's why you have to replot to get the correct values.
This workaround at least should give always crosshairs at the intersection of the major grid lines.
Edit 2: just for "completeness". The factors to get the same (or similar) looking custom dashed pattern on different terminals varies considerably. wxt approx. 11, qt approx. 5.6, pngcairoapprox. 0.25. This is not what I would expect. Furthermore, it looks like the factors slightly depend on x and y as well as graph size. In order to get "exact" crosshairs you might have to tweak these numbers a little further.
Code:
### dashed grid lines with crosshairs at intersections
reset session
TERM = "wxt" # choose terminal
if (TERM eq "wxt") {
set term wxt size 800,600
FactorX = 11. # wxt
FactorY = 11. # wxt
}
if (TERM eq "qt") {
set term qt size 800,600
FactorX = 5.58 # qt
FactorY = 5.575 # qt
}
if (TERM eq "pngcairo") {
set term pngcairo size 800,600
set output "tbDashTest.png"
FactorX = 0.249 # pngcairo
FactorY = 0.251 # pngcairo
}
set multiplot
set ticscale 0,0
Units = 24 # pattern (5,5,4,5,5,0) are 24 units
# set interval and repetition parameters
IntervalsY = 10
RepetitionsY = 1
IntervalsX = 4
RepetitionsX = 3
# initial plot to get graph size
plot x**2
gX = real(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)/IntervalsY/Units/FactorY/RepetitionsY
gY = real(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)/IntervalsX/Units/FactorX/RepetitionsX
# first plot with x-grid lines
set grid xtics lt 1 lc rgb "black" dt (gX*5,gX*5,gX*4,gX*5,gX*5,0)
replot
unset grid
# second plot with y-grid lines
set grid ytics lt 1 lc rgb "black" dt (gY*5,gY*5,gY*4,gY*5,gY*5,0)
replot
unset multiplot
set output
### end of code
Result:
Not really. The closest I can think of is
set grid x y mx my
set grid lt -1 lc "black" lw 1 , lt -1 lc bgnd lw 16
set ticscale 1.0, 0.01
set mxtics 4
plot x**2 lw 2
But that leaves the vertical grid lines solid.

Histogram in GNUplot, each bar with a different color

I am trying to make a barplot with GNUplot, were each bar has a different color. I have found out in the manual that it can be done using lc rgbcolor variable.
My data folder looks like this,
ACB 0.106372
ASW 0.10909
BEB 0.110973
CDX 0.106577
CEU 0.102091
CHB 0.108829
CHS 0.110807
CLM 0.108803
My plot script is as follows,
set style histogram gap 2
set autoscale y
set style fill solid
set xtics rotate by 90 offset 0,-1.2
rgb(r,g,b) = 65536 * int(r*10) + 256 * int(g*10) + int(b*10)
set boxwidth .5
set output "Plot.eps"
plot "plot.tsv" using 2:xticlabels(1):(rgb($2,$2,$2)) with boxes lc rgb variable
I have used the rgb function that is shown in the GNUplot manual. But it shows the following error.
plot "plot.tsv" using 2:xticlabels(1):(rgb($2,$2,$2)) with boxes lc rgb variable
^
"#Plot.plt", line 18: x range is invalid
I can't figure out what the error means.
Please help.
Thanks in advance.
You are actually plotting with style "boxes", not "histograms". That probably is what you want, but whereas for histograms the x coordinate is implicit, for boxes you have to provide an x coordinate in the first column even if you're OK with the ordinal numbers 0,1,2,3,...
So
plot "plot.tsv" using 0:2:xticlabels(1):(rgb($2,$2,$2)) with boxes lc rgb variable
Oh, and you probably want to set the fillstyle also so that the colors are visible:
set style fill solid

The function disappear close to zero

I have problem with plotting fitted function.
The part of the ploted function close to zero disappears and connected with the hyperbola or something which should not be there at all. This happen only if I change set xrange to something smaller than 0. I have to do this because I have lot of data points to close zero so it would look very ugly if I would not changed it.
I tried to use conditionals x>0?f(x):1/0 but it does not help. The hyperbola disappear but the function does not continue down as it should.
I use this code:
set terminal postscript eps size 3.5,2.62 enhanced color
set output "a.eps"
set xrange [-1:]
f(x)=a*b*x/(1+a*x)
fit f(x) "./a" via a, b
plot "./a" w p title "", f(x) w l title "Langmuir isotherm"
That is simply a matter of sampling. The default sampling rate is 100 (show samples), which isn't enough to show fast-varying functions. Increase the sampling rate with e.g.
set samples 1000
to have your function plotted correctly.
A second point is, that discontinuities aren't shown properly if no sample is located exactly at that position. Consider the following plot to demonstrate this:
set xrange [-1:1]
set multiplot layout 2,1
set samples 100
plot 1/x
set samples 101
plot 1/x
unset multiplot
So, if you want to plot the function correctly on both sides of the discontinuity, you must either define a small region around the discontinuity as undefined, or you plot the parts on the left and right separately:
set xrange [-1:]
f(x)=a*b*x/(1+a*x)
fit f(x) "./a" via a, b
left(x) = (x < -1/a ? f(x) : 1/0)
right(x) = (x > -1/a ? f(x) : 1/0)
plot "./a" w p title "", left(x) w l lt 2 title "Langmuir isotherm", right(x) w l lt 2 notitle

Gnuplot: how to add y2 axis scale for different units

I'm plotting data from a file. The data points are in metric units. I want to show a second scale on the right (y2) that's in standard units.
The file represents rocket motor thrust over time. The data are in Newtons. I want to show newtons on the left (this happens by itself, naturally) and pounds force on the right. The conversion is a simple factor (multiply N by 0.2248 to obtain lbf).
I can set y2tics and if I set y2range manually, they appear on the right. What I don't know how to do is set y2range automatically to y1range * a factor.
My eventual solution is to plot twice, once in Newtons on y1 and once in pounds on y2, and make the y2 plot almost invisible:
plot '-' using 1:($2*0.2248) with dots axes x1y2 lc rgb 'white' notitle, \
'' using 1:2 with lines lc rgb '<color>' title '<title>'
The solution above often generates slightly different y scales: with autoragne, gnuplot rounds up the range so the top tick on each axis is a round number, and of course the rounding is different for different units.
Ultimately I end up with Python code that finds the highest thrust value in each graph, then I explicitly set yrange to that number and y2range to that number * 0.2248:
f.write("set yrange [0:%s]; set y2range[0:%s]\n" % (peak_thrust, peak_thrust*NEWTON_LBF));
Here's the end result: http://www.lib.aero/hosted/motors/cesaroni_12-15-12.html (sample graph below)
It seems to me that the easiest way to do this is to simply scale the data:
set y2tics
plot sin(x) w lines, 5*sin(x) w lines axes x1y2
Of course, you're plotting data from a file, so it would look something more like:
set y2tics
FACTOR=0.2248 #conversion factor from newtons to lbf
plot 'datafile' u 1:2 w lines, '' u 1:(FACTOR*$2) w lines
If you're setting the yrange explicitly (which you may need to do):
set yrange [ymin:ymax]
set y2range [ymin*FACTOR:ymax*FACTOR]
Finally, if you really want to rely on autoscaling, you're going to need to do some "gymnastics".
First, set a dummy terminal so we can plot without making a plot:
set term unknown
plot 'datafile' u 1:2 #collect information on our data
Now that we've collected information on the data, we can set our real y2range
FACTOR=0.2248
set y2range [FACTOR*GPVAL_Y_MIN : FACTOR*GPVAL_Y_MAX]
set y2tics nomirror
set ytics nomirror
Now set the terminal and plot the data:
set term ...
set output ...
plot 'datafile' u 1:2 w lines
Version 5.0 added support for this kind of relations between the y and y2 (or also x and x2) axis:
set xrange[0:370]
set ytics nomirror
set y2tics
set link y2 via 0.2248*y inverse y/0.2248
plot x
I know it's an old question and the answer has already been accepted, but I think it's worth sharing my approach.
I simply use modified labels for the x2axis. In your case, this would be
set y2tics ("10" 10/0.2248, "20" 20/0.2248 etc etc...
that can be looped this way
do for [i=0:1000:10] { set y2tics add (sprintf("%i",i) i/0.2248) }
where the for range should be adjusted according to your data (you could use stats and the variable GPVAL_DATA_Y_MAX for complete peace of mind).
Don't forget to
set ytics nomirror
This will give exactly what are you looking for, in (almost) a one liner:
If you want to use a grid and have the converted factors on the x2axis, so that for example to the label y=50 N would correspond y2=11.2 (it keeps things tidy if you use a grid) you can do
do for [i=0:1000:50] { set y2tics add (sprintf("%5.1f",i*0.2248) }
This is the result:

Resources