Default geom_point shapes and antialiasing

1,374 views
Skip to first unread message

Winston Chang

unread,
Jun 2, 2009, 6:11:08 PM6/2/09
to ggplot2
In the graphs I've made with ggplot 2 that have geom_point(), I've found that the default shapes are not properly antialiased when outputting to a bitmap device (like a PNG or on screen), and so they can look pretty bad -- jagged and off-center. This is on Ubuntu Linux, R 2.8.1, and, IIRC, on my Mac with R 2.9.0. (With PDF output, this doesn't seem to be a problem.)

Because of this, I often add a geom_shape_manual() specification that tells it to use shapes that _do_ have proper antialiasing. To me, it seems like this sort of thing shouldn't be necessary. It would be nice if it defaulted to using some of the antialiased shapes. I know that it would be a big deal to change the default shapes for geom_point, but I think it might be worth it, as long as ggplot2 is still in the phase where it's OK to break API.

When I show someone a simple scatterplot, the dots look misshapen, until I add in code to change the point style. In my experience trying to convince people to use ggplot2, one of the best selling points is that it's simple to use, and part of that simplicity is having attractive default parameters.


As for the specific shapes:
- Shapes 15-18 are the only ones that aren't anti-aliased.
15: Square
16: Circle
17: Triangle
18: Diamond
- Shape 16 can be easily replaced with 19, but the others don't have equivalent filled shapes. They could, however, be replaced by shapes 21-25, with a fill that is the same color as the outline.


Then again, if the non-antialiasing of some shapes is just some weird R rendering thing that will be fixed in the near future, then this is all moot.


Here's some code to illustrate the issue, and the resulting PNG from my machine.

cond <- LETTERS[1:25]
xval <- 0:24 %% 5
yval <- 5*floor(0:24 / 5)
df <- data.frame(cond, xval, yval)

ggplot(df, aes(x=xval, y=yval, shape=cond)) + geom_point(fill="red") +
    scale_shape_manual(values=0:25)

shapes.png

shapes.png

Mike Lawrence

unread,
Jun 2, 2009, 7:56:21 PM6/2/09
to Winston Chang, ggplot2
I'm genuinely curious why the various vectorized outputs (pdf, svg,
etc) aren't satisfactory formats for you?
--
Mike Lawrence
Graduate Student
Department of Psychology
Dalhousie University

Looking to arrange a meeting? Check my public calendar:
http://tr.im/mikes_public_calendar

~ Certainty is folly... I think. ~

Winston Chang

unread,
Jun 2, 2009, 9:24:48 PM6/2/09
to Mike Lawrence, ggplot2
There are many cases where I prefer to use bitmaps -- generally when the intended viewing is on a computer screen.

My default behavior for generating graphs that I'm going to send via email or put in a web page is to output a PNG. For powerpoint, I need to use bitmaps. I've also made a few graphs that have thousands of semi-transparent points and have resulted in PDFs that were 1-2 megabytes. Some colleagues have made graphs that take several seconds to render in a PDF viewer, because there are so many elements to draw. I also explore data on my computer screen, and the little misshapen points are a distraction -- for me, at least.

I know that it's possible to output to some vector format and then convert to a bitmap using something like ImageMagick, but this imposes another step which is outside of the R environment, and it's not guaranteed that the conversion tools will be available, especially in Windows... I was running R in Windows for a while. It would have been possible to install ImageMagick and write vector->bitmap conversion scripts that would be called from an R script and work across platforms, but it would be a lot of fiddling for a small payoff.

None of these reasons is a total show stopper for using vector graphics, but the little things add up. If my only goal was to output for printing, then this might not be an issue; but there are many different ways these graphs get used and often low-res (e.g., 72 dpi) bitmaps are the most suitable.

hadley wickham

unread,
Jun 2, 2009, 9:56:19 PM6/2/09
to Winston Chang, Mike Lawrence, ggplot2
> I know that it's possible to output to some vector format and then convert
> to a bitmap using something like ImageMagick, but this imposes another step
> which is outside of the R environment, and it's not guaranteed that the
> conversion tools will be available, especially in Windows... I was running R
> in Windows for a while. It would have been possible to install ImageMagick
> and write vector->bitmap conversion scripts that would be called from an R
> script and work across platforms, but it would be a lot of fiddling for a
> small payoff.
>
> None of these reasons is a total show stopper for using vector graphics, but
> the little things add up. If my only goal was to output for printing, then
> this might not be an issue; but there are many different ways these graphs
> get used and often low-res (e.g., 72 dpi) bitmaps are the most suitable.

What device are you using? I've attached the output I get when saving
to a png on my mac. I think all cairo-based devices should give
similar results.

Hadley


--
http://had.co.nz/

symbols.png

Winston Chang

unread,
Jun 2, 2009, 10:34:17 PM6/2/09
to hadley wickham, Mike Lawrence, ggplot2

What device are you using?  I've attached the output I get when saving
to a png on my mac.  I think all cairo-based devices should give
similar results.



The previously attached graph was generated in Linux, so I think it used the standard X11 device to generate the graph.

Now that I'm at my Mac, I just tried it on this machine. I have two R installations:
1. The Mac R GUI package. Antialiasing for shapes 15-18 works on screen (quartz device), and with png.
2. A terminal-based installation from MacPorts. Antialiasing fails for those shapes on screen (X11 device), but works with png.

In the second setup, when I run X11.options(), it says:

$type
[1] "cairo"

$antialias
[1] "default"



If it helps at all, I have the same non-antialiasing issues with 15-18 using the standard R graphing routines. For those who wants to see all the shapes with standard graphics, type ?pch, and then cut and paste the code it has for pchShow().

JiHO

unread,
Jun 3, 2009, 2:09:56 AM6/3/09
to hadley wickham, ggplot2

On 2009-June-03 , at 03:56 , hadley wickham wrote:

> What device are you using? I've attached the output I get when saving
> to a png on my mac. I think all cairo-based devices should give
> similar results.

saving to png on a mac uses the quartz device (i.e. png(...,
type="quartz") ).

Forcing the cairo device (which is the default for both display and
raster rendering on linux and in X11 on mac) shows the antialiasing
problem.

library(ggplot2)

cond <- LETTERS[1:25]
xval <- 0:24 %% 5
yval <- 5*floor(0:24 / 5)
df <- data.frame(cond, xval, yval)

p <- ggplot(df, aes(x=xval, y=yval, shape=cond)) +
geom_point(fill="red", size=4) + scale_shape_manual(values=0:25)

png("mac.png")
print(p)
dev.off()

png("mac-cairo.png", type="cairo")
print(p)
dev.off()

(for some reason, cairo based rendering is very slow on my MacBook. I
don't know where it gets its Cairo library from).

JiHO
---
http://jo.irisson.free.fr/

Karl Ove Hufthammer

unread,
Jun 3, 2009, 3:06:50 AM6/3/09
to ggplot2
hadley wickham skreiv:

> What device are you using? I've attached the output I get when saving
> to a png on my mac. I think all cairo-based devices should give
> similar results.

I have the same problem on Linux, using the Cairo device. I guess the
problem is that the shapes are filled, not stroked, and that Cairo
antialiasing doesn’t work properly then.

--
Karl

Karl Ove Hufthammer

unread,
Jun 3, 2009, 3:25:24 AM6/3/09
to ggplot2
Karl Ove Hufthammer skreiv:

> I have the same problem on Linux, using the Cairo device. I guess the
> problem is that the shapes are filled, not stroked, and that Cairo
> antialiasing doesn’t work properly then.

?X11 says:

Anti-aliasing is only supported for cairo-based devices, and
applies to graphics and to fonts. It is generally preferable for
lines and text, but can lead to undesirable effects for fills,
e.g. for 'image' plots, and so is never used for fills.

--
Karl

Winston Chang

unread,
Jun 3, 2009, 12:17:02 PM6/3/09
to Karl Ove Hufthammer, ggplot2
I'm not really sure what's going on when you run png(...) in Linux. I just installed the Cairo library in R (this package isn't included by default), and when I run CairoPNG(...), all the shapes are antialiased. Somehow this must be different from the Cairo called when you just run png().

I also tried this on Windows, using the standard graphics, and with the Cairo library. Here's the rundown of how things look:

Mac (R GUI)
- onscreen: quartz - all shapes antialiased
- png: quartz - all shapes antialiased

Mac (R terminal)
- onscreen: X11 (via built-in cairo?) - all shapes antialiased except 15-18
- png: quartz - all shapes antialiased
- png: via CairoPNG() - all shapes antialiased, all text is bold italic

Linux
- onscreen: X11 - all shapes antialiased except 15-18
- png: png (via built-in cairo?) - all shapes antialiased except 15-18
- png: via CairoPNG() - all shapes antialiased

Windows
- onscreen: windows - no shapes antialiased
- png: windows(?) - no shapes antialiased
- onscreen: via CairoWin() - All shapes antialiased (but text is not antialiased)
- png: via CairoPNG() - All shapes antialiased (but text is not antialiased)


So perhaps installing and using CairoPNG is an OK workaround. Fonts are inconsistent across platforms, but I personally find that less annoying than ugly shapes.

For anyone interested in installing Cairo on Linux, I had to run 'sudo apt-get install libxt-dev' before it would properly install.
(From http://www.nabble.com/Cannot-Install-Cairo-Library-td23668909.html )

It's too bad that R relies on external libraries to do the rendering -- it means that different platforms will generated different graphs.

-Winston


shapes_windows.png
shapes_windows_cairopng.png
shapes_linux_cairopng.png
shapes_mac_cairopng.png

hadley wickham

unread,
Jun 4, 2009, 10:27:08 AM6/4/09
to JiHO, ggplot2
On Wed, Jun 3, 2009 at 1:09 AM, JiHO <jo.l...@gmail.com> wrote:
>
> On 2009-June-03  , at 03:56 , hadley wickham wrote:
>
>> What device are you using?  I've attached the output I get when saving
>> to a png on my mac.  I think all cairo-based devices should give
>> similar results.
>
> saving to png on a mac uses the quartz device (i.e. png(..., type="quartz")
> ).

Ah, ok, that's some confusing documentation for png.

Unfortunately there's not much I can do about this from my end. My
only advice would be to write up a small reproducible example, submit
it to R-help and then hope that Brian Ripley has time to do something
about it.

Hadley

--
http://had.co.nz/

Karl Ove Hufthammer

unread,
Jun 4, 2009, 1:46:31 PM6/4/09
to ggp...@googlegroups.com
Quoting hadley wickham <h.wi...@gmail.com>:

> Unfortunately there's not much I can do about this from my end. My
> only advice would be to write up a small reproducible example, submit
> it to R-help and then hope that Brian Ripley has time to do something
> about it.

I'm pretty sure it's intentional. See, e.g.:
http://tolstoy.newcastle.edu.au/R/e4/devel/08/05/1771.html

--
Karl Ove Hufthammer

hadley wickham

unread,
Jun 4, 2009, 5:10:18 PM6/4/09
to Karl Ove Hufthammer, ggp...@googlegroups.com

This seems like a clear counter-example to Brian's claim that's it of no use.

Hadley


--
http://had.co.nz/

Winston Chang

unread,
Jun 4, 2009, 5:15:58 PM6/4/09
to hadley wickham, Karl Ove Hufthammer, ggp...@googlegroups.com
I'll post it to the R-help list and see what they say. In the meantime, you can see a table of results from the myriad rendering methods here:
http://stdout.org/~winston/X/r-antialias/pch.html

-Winston

Karl Ove Hufthammer

unread,
Jun 5, 2009, 4:55:28 AM6/5/09
to ggplot2
hadley wickham skreiv:

>> I'm pretty sure it's intentional. See, e.g.:
>> http://tolstoy.newcastle.edu.au/R/e4/devel/08/05/1771.html
>>
>
> This seems like a clear counter-example to Brian's claim that's it of no use.
>

I’m not sure I understand. Isn’t it more an example of the fact the
antialiasing of fills is *usually* a bad thing, not a good thing? Here’s
another example:

us <- map("state", fill=TRUE, plot=FALSE)
plot(us, type="n", axes=FALSE, asp=1)
polygon(us, col="blue", border=NA)

No antialiasing → looks good
Antialiasing → looks bad

The example is taken from the discussion at:
http://tolstoy.newcastle.edu.au/R/devel/06/08/6391.html

--
Karl Ove Hufthammer

hadley wickham

unread,
Jun 5, 2009, 9:16:39 AM6/5/09
to Karl Ove Hufthammer, ggplot2
On Fri, Jun 5, 2009 at 3:55 AM, Karl Ove
Hufthammer<Karl.Hu...@math.uib.no> wrote:
>
> hadley wickham skreiv:
>>> I'm pretty sure it's intentional. See, e.g.:
>>> http://tolstoy.newcastle.edu.au/R/e4/devel/08/05/1771.html
>>>
>>
>> This seems like a clear counter-example to Brian's claim that's it of no use.
>>
>
> I’m not sure I understand. Isn’t it more an example of the fact the
> antialiasing of fills is *usually* a bad thing, not a good thing? Here’s
> another example:
>
> us <- map("state", fill=TRUE, plot=FALSE)
> plot(us, type="n", axes=FALSE, asp=1)
> polygon(us, col="blue", border=NA)
>
> No antialiasing → looks good
> Antialiasing → looks bad

Polygon fills, antialiasing bad; point fills, antialiasing good?

Hadley

--
http://had.co.nz/

Karl Ove Hufthammer

unread,
Jun 5, 2009, 10:26:12 AM6/5/09
to ggplot2
hadley wickham skreiv:

>> us <- map("state", fill=TRUE, plot=FALSE)
>> plot(us, type="n", axes=FALSE, asp=1)
>> polygon(us, col="blue", border=NA)
>>
>> No antialiasing → looks good
>> Antialiasing → looks bad
>>
>
> Polygon fills, antialiasing bad; point fills, antialiasing good?
>

Sure, but internally they’re all implemented as polygons (see the
function GESymbol in src/main/engine.c), so I’m not sure how we can make
that distinction in practice. Perhaps a new option to X11.options() for
enabling antialiasing for fills (globally) could be useful, though?

--
Karl Ove Hufthammer

Reply all
Reply to author
Forward
0 new messages