Bug 16299 - Line is not cropped correctly in svg() device
Summary: Line is not cropped correctly in svg() device
Alias: None
Product: R
Classification: Unclassified
Component: Graphics (show other bugs)
Version: R-devel (trunk)
Hardware: x86_64/x64/amd64 (64-bit) All
: P5 normal
Assignee: R-core
Depends on:
Reported: 2015-04-03 13:08 UTC by Milan Bouchet-Valat
Modified: 2015-07-22 09:49 UTC (History)
2 users (show)

See Also:

fig1.svg (17.39 KB, image/svg+xml)
2015-04-03 13:09 UTC, Milan Bouchet-Valat
fig2.svg (18.90 KB, image/svg+xml)
2015-04-03 13:10 UTC, Milan Bouchet-Valat
fig3.svg (17.39 KB, image/svg+xml)
2015-04-03 13:10 UTC, Milan Bouchet-Valat
non-Cairo version of fig3.svg (26.56 KB, image/svg+xml)
2015-06-18 23:17 UTC, Paul Murrell
Screenshot of "non-Cairo version of fig3.svg" (3.58 KB, image/png)
2015-06-24 12:54 UTC, Milan Bouchet-Valat

Note You need to log in before you can comment on or make changes to this bug.
Description Milan Bouchet-Valat 2015-04-03 13:08:53 UTC
I've noticed that in some cases, a plotted line goes beyond the plot region and the limits of box.

I have identified two examples.

1) When setting xlim to a maximum value lower than the maximum of the data:
plot(0:100, xlim=c(1, 10), ylim=c(0, 10), type="l", lwd=15, col="dark grey")

See fig1.svg. Notice how the line goes too far on the right (there's also an artifact above the point where it crosses the box), but not on the left.

2) When setting xaxs="i":
plot(0:100, xaxs="i", type="l", lwd=15, col="dark grey")

See fig2.svg. Again, the problem only happens on the right, and not on the left.

3) When calling lines() after plot(), the problem happens on both left and right, and the line is even drawn above the box:
plot(0:100, xlim=c(5, 10), ylim=c(0, 10), type="n", lwd=15, col="dark grey")
lines(0:100, lwd=15, col="dark grey")

See fig3.svg.

I've seen this with both R 3.1.2  on Windows, and with R 3.1.2 and R-devel on Fedora 21, using either Cairo and Xlib.
Comment 1 Milan Bouchet-Valat 2015-04-03 13:09:49 UTC
Created attachment 1769 [details]
Comment 2 Milan Bouchet-Valat 2015-04-03 13:10:07 UTC
Created attachment 1770 [details]
Comment 3 Milan Bouchet-Valat 2015-04-03 13:10:29 UTC
Created attachment 1771 [details]
Comment 4 Milan Bouchet-Valat 2015-06-18 10:08:37 UTC
I'm no longer able to reproduce the two first issues on Windows with R 3.2.0. But the third one remains, and all three remain on Linux with both R 3.2.0 and R-devel.
Comment 5 Martin Maechler 2015-06-18 15:34:20 UTC
I can reproduce this *if* I use svg().
There's no such phenomenon if I use pdf() and possibly very small / faintly if I use the default interactive device on Linux,  x11().

This is about *cropping* and that is partly device dependent.

I've changed the title of the report (but will not do much more; this is not my field of expertise).
Comment 6 Milan Bouchet-Valat 2015-06-18 16:10:38 UTC
It might be small, but it's still visible with the Xlib/Cairo device. Of course it's more of an issue with SVG since you want high-quality graphics in that case.
Comment 7 Paul Murrell 2015-06-18 23:17:37 UTC
Created attachment 1848 [details]
non-Cairo version of fig3.svg
Comment 8 Paul Murrell 2015-06-18 23:20:04 UTC
This may be a Cairo graphics issue (?)

The following code generates a non-Cairo version of fig3 that does NOT exhibit the problem ...

# original code to show problem on Cairo screen device
plot(0:100, xlim=c(5, 10), ylim=c(0, 10), type="n", lwd=15, col="dark grey")
lines(0:100, lwd=15, col="dark grey")

# generate visually identical grid version that still shows problem
# (on Cairo screen device)

# generate non-Cairo SVG version that does NOT show the problem
# (file attached)
Comment 9 Milan Bouchet-Valat 2015-06-19 07:41:38 UTC
I see the same issue in the SVG you attached. The grey line clearly does not stop before the black box.

Also, the bug happens with Xlib, not only Cairo.
Comment 10 Paul Murrell 2015-06-24 03:27:20 UTC
- Xlib looks ok on my Linux machine
- the SVG that I attached looks ok in Firefox on Linux and Windows for me

... PLUS, according to ...


... Cairo_Clip() performs a "+ 1" to the clip rect, as per X11_Clip() ...

    /* Add 1 per X11_Clip */
    cairo_rectangle(xd->cc, x0, y0, x1 - x0 + 1, y1 - y0 + 1);

... which is confirmed in ...


... with this code in X11_Clip() ...

    xd->clip.x = (unsigned short) x0 ;
    xd->clip.width = (unsigned short) x1 - (unsigned short) x0 + 1;

... BUT Cairo is dealing with doubles, NOT unsigned shorts as in X11. SO Cairo should NOT perform the "+ 1" and should instead act as vector formats like PDF, which ...


... shows does NOT have the "+ 1" ...

    pdfClip(x0, x1, y0, y1, pd);

NOTE that the "+ 1" has some basis for the X11 case because conversion from double to unsigned short drops the fractional part of the double, as stated in ...

Comment 11 Milan Bouchet-Valat 2015-06-24 12:54:22 UTC
Created attachment 1851 [details]
Screenshot of "non-Cairo version of fig3.svg"

Just to be sure: you don't see the overlapping I'm seeing in the attached screenshot of the SVG you attached?
Comment 12 Paul Murrell 2015-06-24 20:38:32 UTC
I see exactly that "overlap".  The difference is that I think it is correct behaviour.  The black line that draws the border on the plot region (and has non-zero width) is centred on the zero-width boundary of the plot region, so that border line extends both inside and outside the plot region (a little bit).  The thick grey line is clipped to the plot region, so stops right at the edge of the plot region (half-way through the black line).

The behaviour of the Cairo-device SVG is different.  That appears (to me) to extend *beyond* the plot region (on the right-hand side).
Comment 13 Milan Bouchet-Valat 2015-06-25 08:04:21 UTC
Ah, so now at least we know what we're talking about. :-)

I don't consider this as correct, though. Or maybe that's correct from the backend POV, and I understand how it happens, but it would be nice if the lines never overlapped with the box -- just like what happens when calling plot(.., type="l"), with the box being plotted after the lines.
Comment 14 Paul Murrell 2015-07-16 00:42:07 UTC
If you want the box drawn last, you can call box().
Comment 15 Milan Bouchet-Valat 2015-07-22 09:49:17 UTC
Of course I can do that, but I think it should look that way by default...