#195 Tics and grid slightly outside border.

Dan Sebald

For some choice of range the tics and grid can land
slightly beyond a border line.


OK, I think I have narrowed this down. It has to do
with the xrange being slightly less than a whole
number. You may or may not feel this is gnuplot's
problem or Octave should be worrying about this. I'll
just describe it.

Launch gnuplot with the -nofeedback option. Then type
the following set of commands:

set xrange [0:1.99805]
set grid
plot sin(x)
set xrange [0:2] replot
set xrange [0:1.99805]

You should notice this behavior on the right border
toggling back and forth. So, yes it does seem that the
border is being drawn a pixel to the left because of
the 1.99805. So I guess the question is whether a grid
line should be drawn at all in this scenario. It
probably has something to do with rounding.

If you run gnuplot without the -nofeedback option, the
feedback will slightly readjust the x length and the
rounding will behave differently. But if you move your
x-window about a bit, in some locations you should see
the right border shifted slightly to the left. I guess
what I'm saying is that on your particular system, if
you run "gnuplot -nofeedback" and then

set xrange [0:1.99805]
set grid
set term png
set output 'junk.png'
plot sin(x)
set output

You should get a PNG file with the aberration. Your
X11 system may behave slightly different depending upon
your system settings.


I looked into this issue of the grid line and tics to
the right of the right border. There is a lot of code
for the tics, and I notice a comment in the code:

/* FIXME HBB 20010121: keeping adding 'step' to 'tic' is
* begging for rounding errors to strike us. */
/* HBB 20010410: ... and strike they did :-( */

So there is probably an issue having to do with that.
Of course, one thing that could be done is a sanity
check to make sure no tics are drawn if outside xleft,
xright, xbot, xtop. But those variables are not in the
same C file.... Also, there should be a bit of code
that would round the border up to 2.0 if [0:1.99805].
What I mean, is that the range should probably be
rounded to the nearest, oh, 1/2% of the length. That
is, when it comes to the final computation of the
range, treat 1.99805 as follows

xmax - xmin = 1.99805

(xmax - xmin)*0.005 = 0.0099903

which means we should round to the nearest 0.01, i.e.
1.99805 rounds to 2.0. It is a little bit difficult to
imagine an elegant algorithm to do this, but it may
involve working with the exponents of floats in
exponential notation. (Can't think of any C constructs
to do that.) Or perhaps working with logarithms.

Not proposing this be done, but I hope you catch my drift.


  • Dan Sebald
    Dan Sebald

    PNG file showing tics slightly outside right border.

  • Dan Sebald
    Dan Sebald

    Logged In: YES

    I looked at this again. To remove the grid line from
    outside the plot, I commented out the following lines of
    code from gen_tics() in axis.c:

    /\* \{\{\{  a few tweaks and checks \*/
    /\* watch rounding errors \*/

    // end += SIGNIF * step;
    /* HBB 20011002: adjusting the endpoints doesn't make sense if
    * some oversmart user used a ticstep (much) larger than the
    * yrange itself */
    // if (step < (fabs(lmax) + fabs(lmin))) {
    // internal_max = lmax + step * SIGNIF;
    // internal_min = lmin - step * SIGNIF;
    // } else {
    internal_max = lmax;
    internal_min = lmin;
    // }

    This gen_tics() should be re-examined.

  • Dan Sebald
    Dan Sebald

    Logged In: YES

    The reason I think what this patch is an improvement is that
    it handles rounding artifacts in several different places
    where they crop up rather than trying to solve them all with
    a single conditional test right before the tic-placement in
    the for-loop. This patch does not have any type of SIGNIF
    and tolerance based upon the range. It only deals with
    rounding effects at the level of DBL_EPSILON or order thereof.

    Furthermore, the tic placement is done more in an
    integerized fashion, i.e., an integer start and integer end
    corresponding to the start and end values after factoring
    out the step increment are computed. We then know before
    entering the loop what the number of intervals, N_int,
    should be. (An interval is the major tic with the group of
    potential minor tics to its positive side.)

    Being more accurate with respect to the integer equivalents,
    the code address any roundoff problem with the major tic end
    point as:

        /\* Address rounding issues in the following way \*/
        if \(i\_tic == \(N\_int - 1\)\)
        tic = end;
        tic = start + i\_tic \* step;

    to avoid losing a tic at the end range.

    I've checked every example in 'all.dem' for consistency
    before and after the patch and that the patch fixes the bug
    of grid lines sometimes landing outside the borders. In
    fact, 'all.dem' helped a great deal for debugging.


  • Dan Sebald
    Dan Sebald

    bug fix and integerization of tic placement

  • Ethan Merritt
    Ethan Merritt

    Logged In: YES

    As part of preparing for a 4.2 release, I want to make it clear
    what is and is not still on my (sfeam) MUST DO list. This patch
    is not on that list. If you think it should be, please speak up

    Many of these bugs are stale and can be closed out altogether.

  • Ethan Merritt
    Ethan Merritt

    • priority: 5 --> 2