|
From: Daniel J S. <dan...@ie...> - 2006-05-28 06:27:50
|
I've been tweaking the examples in prob.dem to be a little more accurate and mathematically correct visually. And it occurs to me that it might be nice for gnuplot to handle discontinuities in an elegant way. When a person is writing on a chalk board or scribbling on paper, a lot of time we just treat a discontinuity as though it is some kind of sharp transition, i.e., we connect the left and right limits and take it as understood as a discontinuity. But on second thought, why shouldn't a plotting program be able to leave out the line connecting the left and right limits of a discontinuity? Here's an example and a couple thoughts. Here's an attempt to plot a function for which f(x) = 0 for x < 1 and f(x) = 1/x for x >= 1; first with a plot for such a definition and second in a piecewise fashion that works, but some might consider a hack: f(x) = x<1?0:1/x set xrange [-1:4] set yrange [-0.1:1.1] set samples (4-(-1))*50 + 1 set term x11 1 plot f(x) set term x11 2 plot x<1?f(x):x==1?0:1/0 with lines lc rgb "red", x>=1?f(x):1/0 with lines lc rgb "red" Notice that in the above I set the number of samples and limits so that x=1.0, the discontinuity is selected as a plot point. Wouldn't it be nice if one could somehow define some function g(x) so that plot g(x) produced just what the second plot did? (This may not work... so bear with me.) For example, say that one could attach left and right limits to the value 1/0. (I'll do this with some concocted syntax for now.) g(x) = x<1?0:x>1?1/x:(1/0,0,1/x) which means that if the value x==1 is encountered in this case the point is treated as 0 connecting the point to the left and 1/1 = 1 when connecting the point to the right. The f(x) as defined at top would still plot the way it currently does, and if one simply put 1/0 rather than (1/0,<left limit>,<right limit>) things would still plot the way they currently do. I'm not sure what the container class looks like in general, but with all the extra fields in gnuplot, you'd think that when the value is 1/0 and other fields like xhigh and xlow make no sense, they could be use instead for left and right limits. The only problem is choosing the plot range and samples correctly so that the discontinuity ends up being selected. So in some sense, this might not be a feature that any but the most informed users would be able to figure out. Maybe we can conclude defining discontinuities as part of a function is a bad idea, I don't know. OK, well, then here is something else that would make plotting discontinuities a little nicer. Say f(x) is defined as above f(x) = x<1?0:1/x and I were able to plot subranges in my plot plot [x=-1:1-epsilon] f(x) with lines lc rgb "red", [x=1+epsilon:4] f(x) with lines lc rgb "red" where epsilon is either a constant defined to be the resolution of real numbers or it is command syntax meaning the same thing. The evaluation of f(1-epsilon) would of course be 0, but when all is said in done in the plotting process 1-epsilon is basically cast to 1.0. (BTW, why does putting the range in the plot override the "set xrange [#,#]" command? You'd think if it were autoscale, then yes override, but otherwise why should it?) Alright, well can this be improved upon? Could the syntax of a plot range be extended as, say, plot [x=-1:1-epsilon:1+epsilon:4] f(x) ? Which means to draw two red segments, one from -1 to 1-epsilon and from 1+epsilon to 4. That way we get rid of the multiple sections of "lc "red"" stuff. But that too is limiting, let's say we want two functions with discontinuities. I'd say combine the previous two suggestions and you'd get plot [x=-1:1-epsilon:1+epsilon:4] f(x), [x=-1:2-epsilon:2+epsilon:4] f(x-1) being a red function with a discontinuity and a green, delayed function with a discontinuity. [I say delayed because in engineering we usually think of the x axis as time and f(x-D) as a delay of D.] Two discontinuities? plot [x=-1:1-eps:1+eps:2-eps:2+eps:4] ff(x) and so on. I kind of like the latter syntax now that I write it. Dan |
|
From:
<br...@ph...> - 2006-05-28 12:04:22
|
Daniel J Sebald wrote: > I've been tweaking the examples in prob.dem to be a little more accurate > and mathematically correct visually. And it occurs to me that it might > be nice for gnuplot to handle discontinuities in an elegant way. Would be nice if it were actually possible, but it isn't. Seriously. The only way for gnuplot to distinguish a true discontinuity from a mere fast variation in a plotted function would be to add a full analytical maths engine. And that's before you consider that for data plots the whole concept of continuity doesn't exist in the first place. If people want an analytic maths engine that understands calculus, I hope they'll know where to find MuPAD, Maple, Mathematica or something like them. > But on second thought, why shouldn't a plotting program be able to > leave out the line connecting the left and right limits of a > discontinuity? Because it can't really know whether that's discontinuity or not. > The only problem is choosing the plot range and samples correctly so > that the discontinuity ends up being selected. No. The problem is that tuning of equidistant sampling can typically only be done to match *one* discontinuity --- but there's no way of telling how many discontinuities a plotted function might have in the plotted range, or where they'll be. > OK, well, then here is something else that would make plotting > discontinuities a little nicer. Say f(x) is defined as above > > f(x) = x<1?0:1/x > > and I were able to plot subranges in my plot > > plot [x=-1:1-epsilon] f(x) with lines lc rgb "red", [x=1+epsilon:4] f(x) > with lines lc rgb "red" You *are* able to do that, once you switch to parametric mode. set parametric set trange [0:1-epsilon] x1(t)=-1+2*t x2(t)=1+3*t plot x1(t),f(x1(t)), x2(t), f(x2(t)) > the plotting process 1-epsilon is basically cast to 1.0. (BTW, why does > putting the range in the plot override the "set xrange [#,#]" command? Because that's what _all_ optional elements of a 'plot' command do, in gnuplot: they override whatever the default for some property of the plot might be. 'with <style>' overrides 'set style function' or 'set style data', 'linetype <n>' overrides the colour, and a range overrides the corresponding 'set *range'. |
|
From: Daniel J S. <dan...@ie...> - 2006-05-28 14:26:27
|
Hans-Bernhard Br=F6ker wrote:
>> The only problem is choosing the plot range and samples correctly so=20
>> that the discontinuity ends up being selected. =20
>=20
>=20
> No. The problem is that tuning of equidistant sampling can typically=20
> only be done to match *one* discontinuity --- but there's no way of=20
> telling how many discontinuities a plotted function might have in the=20
> plotted range, or where they'll be.
I had in mind each subrange could be treated with the same number of poin=
ts and not get too elaborate. If it is oversampling on one region, so be=
it. (In essence, pretty much the same behavior of the parametric mode e=
xample you give.)
>=20
>> OK, well, then here is something else that would make plotting=20
>> discontinuities a little nicer. Say f(x) is defined as above
>>
>> f(x) =3D x<1?0:1/x
>>
>> and I were able to plot subranges in my plot
>>
>> plot [x=3D-1:1-epsilon] f(x) with lines lc rgb "red", [x=3D1+epsilon:4=
]=20
>> f(x) with lines lc rgb "red"
>=20
>=20
> You *are* able to do that, once you switch to parametric mode.
>=20
> set parametric
> set trange [0:1-epsilon]
> x1(t)=3D-1+2*t
> x2(t)=3D1+3*t
> plot x1(t),f(x1(t)), x2(t), f(x2(t))
Oh yeah, parametric mode. (All the possibilities!) I will include this =
for a couple examples then, thanks.
I still think
plot [-1:1-eps,1:3] pareto(x), [-1:4] cos(x)
would be nicer. Granted, parametric works.
>=20
>> the plotting process 1-epsilon is basically cast to 1.0. (BTW, why=20
>> does putting the range in the plot override the "set xrange [#,#]"=20
>> command? =20
>=20
>=20
> Because that's what _all_ optional elements of a 'plot' command do, in=20
> gnuplot: they override whatever the default for some property of the=20
> plot might be. 'with <style>' overrides 'set style function' or 'set=20
> style data', 'linetype <n>' overrides the colour, and a range overrides=
=20
> the corresponding 'set *range'.
Well, that was my line of thinking. When I say
plot x ls 4, x**2
the line style of 4 applies *only* to the first graph. It does not apply=
to all the graphs on the plot. But I guess since {xrange} is before all=
the functions it could be argued it should apply to all functions.
Dan
|
|
From: Daniel J S. <dan...@ie...> - 2006-05-28 20:23:39
|
Daniel J Sebald wrote: > I still think > > plot [-1:1-eps,1:3] pareto(x), [-1:4] cos(x) > > would be nicer. Granted, parametric works. Well, after thinking about this, a slight change of heart. The above syntax would be convenient. The thing is, if the function has not just a discontinuity, but also a singularity then often one wants a higher density sampling near the singularity. To get a non-uniform sampling requires parametric mode. Dan |
|
From: James R. V. Z. <jr...@co...> - 2006-06-03 01:07:48
|
Daniel J Sebald <dan...@ie...> wrote:
> why shouldn't a plotting program be able to leave out the line
> connecting the left and right limits of a discontinuity?
We could implement an optional threshold on the maximum slope of the
line. For example:
set maxstepy {<fraction>}
If the difference between successive y values exceeds <fraction> of
the graph height, then that line segment is omitted. <fraction> is
a number between 0 and 1. For "set maxstepy" with no number,
<fraction> defaults to 1/3.
set maxstepx {<fraction>}
If the difference between successive x values exceeds <fraction> of
the graph width, then that line segment is omitted. <fraction> is a
number between 0 and 1. For "set maxstepx" with no number,
<fraction> defaults to 1/3.
unset maxstepy
unset maxstepx
Return to the default condition, in which all line segments are
drawn, regardless of the change in y (resp. x) values.
- Jim Van Zandt
|
|
From: Daniel J S. <dan...@ie...> - 2006-06-06 21:58:26
Attachments:
binom-fill-between.png
binom-using-histeps.png
|
James R. Van Zandt wrote:
> Daniel J Sebald <dan...@ie...> wrote:
>
>> why shouldn't a plotting program be able to leave out the line
>> connecting the left and right limits of a discontinuity?
>
>
> We could implement an optional threshold on the maximum slope of the
> line. For example:
>
> set maxstepy {<fraction>}
>
> If the difference between successive y values exceeds <fraction> of
> the graph height, then that line segment is omitted. <fraction> is
> a number between 0 and 1. For "set maxstepy" with no number,
> <fraction> defaults to 1/3.
>
> set maxstepx {<fraction>}
>
> If the difference between successive x values exceeds <fraction> of
> the graph width, then that line segment is omitted. <fraction> is a
> number between 0 and 1. For "set maxstepx" with no number,
> <fraction> defaults to 1/3.
>
> unset maxstepy
> unset maxstepx
>
> Return to the default condition, in which all line segments are
> drawn, regardless of the change in y (resp. x) values.
It's an idea that makes sense, but I wonder if it wouldn't cause unexpected problems. It's difficult to pick a value of 1/3 for the slope because taking into consideration the scale of x compared to y a slope of 1/3 could be just fine; as could 3e5 depending upon circumstances.
Checking for successive samples where the slope changes drastically probably isn't a solution either because if one plots noise from the random number generator, that will have sets of three points where the slope changes drastically from one pair of points to the next.
I think the only way to deal with a discontinuity in a general way is for a point in the data set to be 1/0. That would require picking data points right on the discontinuity to ensure it is treated correctly. But then that requires some form of non-uniform sampling, and so on. Hans pointed out some problems with defining discontinuities.
...
I've put together a patch on SourceForge cleaning up the probability density and distribution demos. The functions are properly defined for all of the real line or set of integers. Parameters are range checked.
This should give a variety of examples of discontinuities and how to deal with them:
o Choosing sampling so that the discontinuity is part of the plotted points.
o Plotting two different ranges, one on each side of the discontinuity, very near the discontinuity if not on the discontinuity.
o Casting float values to integers when appropriate.
o Using the histeps (steps, fsteps) style when appropriate.
For example, below are plots for just one of the many CDFs. In this case a discrete random variable. (Technically, the discrete r.v. should be either a probability mass function or delta functions, but I figured I'd leave the histograms as is for prob2.dem.) In the first plot (before patch) the idea is to use a high enough sampling to make the discrete steps look marginally good. But gnuplot has a histeps feature, so rather than do that, histeps are used in the second plot and all the points of the sample range are cast to an int because now the pdf for a binomial random variable requires the input value be an int. All those points in between the integers are simply extraneous.
Of course, it would be nice to not have those points in between, but it isn't possible to have multiple plotting ranges and samplings. I personally think that would be a nice gnuplot feature, e.g.,
plot [0:1-eps] funcwithdiscontinuity(x) lt 1, [1:5] funcwithdiscontinuity(x) lt 1
plot [-2:1:12] binom(x,1,0.5), [-2:12] normal(x,0,1)
so that one can plot multiple portions of functions, or individual functions. As for the syntax, I don't know how one would specify what the number of samples should be, as opposed to the sampling interval. The examples I've given in the revamped demo work, but it isn't the most convenient. Anyway...
People will have preference to whether a line should be connecting a discontinuity, but if one desires the line be present I think the preference is for the line connecting the right and left limits of a discontinuity to be vertical as opposed to the slightly sloped line that comes about from uniform sampling. "with steps" gives us that, but in many cases the steps appearance isn't always appropriate where parts of the function are continuous.
Regarding this, it might be nice for steps to have a version where the vertical lines are not plotted, just the horizontal lines. Mathematically that is more appropriate, and an analog oscilloscope trace often looks to have no vertical lines with unfiltered reconstructed signals.
Also note in this example plots that after the patch, the definition for the distribution is correct for all of x. So the negative values of the PDF, after the patch, look correct.
Dan
PS: fsteps/histeps/steps might have worked syntactically better as lsteps/csteps/rsteps. (I'm guessing "fsteps" means forward steps or front steps.)
|