2
votes

I am trying to plot a function that contains discontinuities in gnuplot. As a result, gnuplot automatically draws a vertical line connecting the jump discontinuities. I would like to remove this line. I have looked around and found two solutions, none of which worked: One solution was to use smooth unique when plotting, and the other one was to define the function in a conditional form and remove the discontinuity manually. The first solution simply did not make any changes to the plot (at least visually). The second solution seemed to move the location of the jump discontinuity to left or right, not get rid of the vertical line. Please note that I would like to plot with lines. I know with points works, but I do not wish to plot with points.

set sample 10000
N=50
l1(x)=2*cosh(1/x)
l2(x)=2*sinh(1/x)
Z(x)=l1(x)**N+l2(x)**N
e(x)=(-1/Z(x))*(l2(x)*l1(x)**(N-1)+l1(x)*l2(x)**(N-1))
plot e(x)

Produces:

2
Possible duplicate of Gnuplot's Graphic Jump - user8153
@user8153: I tried with points and it looks fine. However, this is an analytical curve that I want to superimpose on Monte Carlo data points; thus, I would like it to be with lines. I tried the conditional solution with lines and I still get the same plot :/ - Ptheguy
@user8153: I guess if I do (abs(e(x)) < 0.999999999999999 ? e(x) : 1/0) w lines it works fine. But there are so many 9s!! Perhaps there's a better solution? - Ptheguy

2 Answers

4
votes

If all you need to do is to remove the vertical line at the singularity you could use conditional plotting:

plot (x<0 ? 1/x : 1/0)  w l ls 1, (x>0 ? 1/x : 1/0) w l ls 1

enter image description here

However, your function is more complicated: it cannot be numerically evaluated in a region around 0:

set grid
set xrange [-0.3:0.3]
plot e(x) with linespoints

enter image description here

If Mathematica is to be trusted, the function e(x) goes to 1 and -1 as x approaches 0 from the left and the right, respectively. However, you see in the picture above that gnuplot fails to properly evaluate the function already at x=0.1. print e(0.1) gives -0.0, and print e(0.05) already gives NaN. In this region the numerator and denominator of the function e(x) get too large to be handled with floating point numbers.

You can either exclude this region using conditional plotting,

plot (x<-0.15 ? e(x) : 1/0)  w l ls 1, (x>0.15 ? e(x) : 1/0) w l ls 1

enter image description here

or you have to rewrite the function e(x) so you avoid extremely large values in its evaluation (if that is possible). Alternatively you can use a software package that can switch to higher precision, such as Mathematica.

2
votes

You can redefine your function e(x) to avoid calculations of large exponentials like

e(x) = -(l2(x)/l1(x) + (l2(x)/l1(x))**(N-1))/(1 + (l2(x)/l1(x))**N)

Now you always calculate l2(x)/l1(x) before taking the power.

For your high sampling rate of 10000, this still gives some undefined points near the singularity, so that you have not connecting line. For lower sampling rates of e.g. 1000 you would also see a line crossing zero. To avoid that you can use an odd sampling rate:

set sample 1001
N=50
l1(x)=2*cosh(1/x)
l2(x)=2*sinh(1/x)
Z(x)=l1(x)**N+l2(x)**N
e(x) = -(l2(x)/l1(x) + (l2(x)/l1(x))**(N-1))/(1 + (l2(x)/l1(x))**N)

set autoscale yfix
set offsets 0,0,0.05,0.05
plot e(x) with lines

enter image description here