Patch - Tick marks and grid lines are not aligned when using vectorial backends

When using a vectorial backend like PS or PDF, I noticed tick marks
and grid lines are not perfectly aligned.

Here is a little script revealing the problem:

    import os
    from pylab import *

    rc('axes', linewidth=0.5, axisbelow=True)
    rc('xtick', direction='out')
    rc('ytick', direction='out')

    t = arange(0.0, 2.0, 0.01)
    s = sin(2*pi*t)
    plot(t, s, linewidth=1.0)

    title('Tick marks, grid lines and other marks should be aligned')
    xlabel('time (s)')
    ylabel('voltage (mV)')
    grid(True, linestyle='-', color='#d3d3d3')

    axhline(0.5, linewidth=0.5)
    plot([0.5], [0.5], '+')
    plot([1.0], [0.5], marker=0)

    savefig('testchart.eps')
    savefig('testchart.png')
    show()

The attached file testchart-misaligned.eps shows the result with the
PS backend: tick marks and grid lines are not perfectly aligned, which
is bad; but the "+" mark placed in the plot is correctly aligned with
the grid lines, as expected.

In the attached file testchart-misaligned.png, produced with the Agg
backend, this is the opposite: tick marks and grid lines are perfectly
aligned, but the "+" mark is not exactly over the grid lines.

I think this is caused by a workaround used in lines.py, in methods
_draw_tickleft, _draw_tickright, _draw_tickup and _draw_tickdown,
consisting in adding 0.5 to marks coordinates in order to place them
in pixel center. This is good for bitmap backends like Agg, but it's
bad for vectorial backends like PS, PDF and SVG. I propose to remove
this behavior from lines.py and move it in _backend_agg.cpp.

The attached file alignment.patch is a patch implementing this proposition.

The files testchart_aligned.eps and testchart_aligned.png show the
results with the PS and Agg backends after applying the patch:
everything is aligned.

Do you agree to apply this patch, or have I misunderstood something? :slight_smile:

Cheers,

-- Nicolas Grilly

testchart_aligned.eps (134 KB)

testchart_aligned.png

testchart_misaligned.eps (134 KB)

testchart_misaligned.png

alignment.patch (2.75 KB)

John,

Have you seen this patch I proposed several days ago, during your
vacations? Can you reproduce the problem on your machine and do you
agree with the solution?

Thanks,

Nicolas

=== My original post hereunder: ===

When using a vectorial backend like PS or PDF, I noticed tick marks
and grid lines are not perfectly aligned.

Here is a little script revealing the problem:

    import os
    from pylab import *

    rc('axes', linewidth=0.5, axisbelow=True)
    rc('xtick', direction='out')
    rc('ytick', direction='out')

    t = arange(0.0, 2.0, 0.01)
    s = sin(2*pi*t)
    plot(t, s, linewidth=1.0)

    title('Tick marks, grid lines and other marks should be aligned')
    xlabel('time (s)')
    ylabel('voltage (mV)')
    grid(True, linestyle='-', color='#d3d3d3')

    axhline(0.5, linewidth=0.5)
    plot([0.5], [0.5], '+')
    plot([1.0], [0.5], marker=0)

    savefig('testchart.eps')
    savefig('testchart.png')
    show()

The attached file testchart-misaligned.eps shows the result with the
PS backend: tick marks and grid lines are not perfectly aligned, which
is bad; but the "+" mark placed in the plot is correctly aligned with
the grid lines, as expected.

In the attached file testchart-misaligned.png, produced with the Agg
backend, this is the opposite: tick marks and grid lines are perfectly
aligned, but the "+" mark is not exactly over the grid lines.

I think this is caused by a workaround used in lines.py, in methods
_draw_tickleft, _draw_tickright, _draw_tickup and _draw_tickdown,
consisting in adding 0.5 to marks coordinates in order to place them
in pixel center. This is good for bitmap backends like Agg, but it's
bad for vectorial backends like PS, PDF and SVG. I propose to remove
this behavior from lines.py and move it in _backend_agg.cpp.

The attached file alignment.patch is a patch implementing this proposition.

The files testchart_aligned.eps and testchart_aligned.png show the
results with the PS and Agg backends after applying the patch:
everything is aligned.

Do you agree to apply this patch, or have I misunderstood something? :slight_smile:

Cheers,

-- Nicolas Grilly

testchart_aligned.eps (134 KB)

testchart_aligned.png

testchart_misaligned.eps (134 KB)

testchart_misaligned.png

alignment.patch (2.75 KB)

No, I missed it the first time around, thanks for resending. I've
been battling these half-center alignment problems since we added the
agg backend -- search throughout the _backend_agg.cpp backend for
"snapto". I do two things differently from you, and we need to
decide on the right approach and do it consistently.

+ ppath->vertex(i, &x, &y);
+ x = x - 0.5;
+ y = y + 0.5;
+ ppath->modify_vertex(i, x, y);

You are subtracting from x and adding to y, and preserving the
original float, whereas I have been truncating to int and adding 0.5
to insure that the number is a pixel center. Eg,

  //snapto pixel centers
  l = (int)l + 0.5;
  b = (int)b + 0.5;
  r = (int)r + 0.5;
  t = (int)t + 0.5;

What is the justification for subtracting from x and adding to y? And
do you agree that it is preferable to first truncate to an int before
doing the 0.5 offset to insure the pixel center?

I do agree that it makes more sense to do this in the backend since
the notion of pixel center has no place in the vector backends. Would
you consider looking over the rest of backend agg and making sure this
is applied consistently and correctly? In the past, I have been only
applying this adjustment on horizontal and vertical lines, but perhaps
we should apply it to all vertices in the agg backend regardless, as
you are doing in your patch. I would love to vanquish this pesky
problem once and for all -- it seems that everytime I push it down in
one place, it crops up in another.

JDH

···

On 2/28/07, Nicolas Grilly <nicolas.grilly@...475...> wrote:

Have you seen this patch I proposed several days ago, during your
vacations? Can you reproduce the problem on your machine and do you
agree with the solution?