72

Maybe it is a silly question, but I couldn't find the answer in the handbook of ggplot2 nor with "aunt" google...

How do I plot a circle with ggplot2 as an additional layer if I have a middle point and a diameter? Thanks for your help.

tonytonov
  • 25,060
  • 16
  • 82
  • 98
Dominik
  • 2,753
  • 7
  • 28
  • 32
  • 3
    Aunt Google was more responsive to me. [This](http://groups.google.com/group/ggplot2/browse_thread/thread/7f4238b5658e85bb) might be of some help. – joran Jul 28 '11 at 17:13

6 Answers6

90

A newer, better option leverages an extension package called ggforce that defines an explicity geom_circle.

But for posterity's sake, here's a simple circle function:

circleFun <- function(center = c(0,0),diameter = 1, npoints = 100){
    r = diameter / 2
    tt <- seq(0,2*pi,length.out = npoints)
    xx <- center[1] + r * cos(tt)
    yy <- center[2] + r * sin(tt)
    return(data.frame(x = xx, y = yy))
}

And a demonstration of it's use:

dat <- circleFun(c(1,-1),2.3,npoints = 100)
#geom_path will do open circles, geom_polygon will do filled circles
ggplot(dat,aes(x,y)) + geom_path()

enter image description here

joran
  • 169,992
  • 32
  • 429
  • 468
  • Thanks Joran, that was what I'm looking for... I'm just wondering, that you have to go with the function to realize that in ggplot. If I remember it correctly, plot have a build in function for that. But this plots just look way nicer ;-) – Dominik Jul 28 '11 at 20:25
  • @Dominik - Indeed, there is `grid.circle`, but to make that work will require some knowledge of the `grid` system. – joran Jul 28 '11 at 20:29
24

If the purpose is only to annotate a circle, you can simply use annotate with geometry "path". No need to create a data frame or function:

#g is your plot
#r, xc, yc are the radius and center coordinates

g<-g+annotate("path",
   x=xc+r*cos(seq(0,2*pi,length.out=100)),
   y=yc+r*sin(seq(0,2*pi,length.out=100)))
Luis
  • 341
  • 2
  • 3
17

Hi the following code from ggplot2 Google group may be useful:

dat = data.frame(x=runif(1), y=runif(1))
ggplot() + scale_x_continuous(limits = c(0,1)) +
scale_y_continuous(limits = c(0,1))+
geom_point(aes(x=x, y=y), data=dat, size=50, shape=1, color="gold4")

Which Produces: enter image description here

I hope it gets you started in hacking up custom examples for your purpose.

Shreyas Karnik
  • 3,953
  • 5
  • 27
  • 26
  • 1
    I could be wrong, but I don't think this method addresses the OP's question, which was how to draw a circle *given a center and diameter*. It will be very tough to get the correct diameter using the size aesthetic. – joran Jul 28 '11 at 18:00
  • Ya I agree, it was just a pointer in the right direction not a complete solution. – Shreyas Karnik Jul 28 '11 at 19:42
  • Thanks for that hint Neo_me, but the way Joran posted fits better for my needs. – Dominik Jul 28 '11 at 20:27
  • Great to see this, this was more what I was looking for. Thanks – nate Jan 26 '16 at 20:52
15

with ggplot2 >= 0.9 you can also do

library(grid)
qplot(1:10, 1:10, geom="blank") +
  annotation_custom(grob=circleGrob(r=unit(1,"npc")), xmin=2, xmax=4, ymin=4, ymax=6)
baptiste
  • 75,767
  • 19
  • 198
  • 294
11

For posterity's sake here is a more flexible circle solution using annotate and geom_ribbon that supports fill, color, alpha, and size.

gg_circle <- function(r, xc, yc, color="black", fill=NA, ...) {
    x <- xc + r*cos(seq(0, pi, length.out=100))
    ymax <- yc + r*sin(seq(0, pi, length.out=100))
    ymin <- yc + r*sin(seq(0, -pi, length.out=100))
    annotate("ribbon", x=x, ymin=ymin, ymax=ymax, color=color, fill=fill, ...)
}
square <- ggplot(data.frame(x=0:1, y=0:1), aes(x=x, y=y))
square + gg_circle(r=0.25, xc=0.5, yc=0.5)
square + gg_circle(r=0.25, xc=0.5, yc=0.5, color="blue", fill="red", alpha=0.2)
Trevor
  • 434
  • 4
  • 8
5

Also try this,

 ggplot() + geom_rect(aes(xmin=-1,ymin=-1,xmax=1,ymax=1), fill=NA) + coord_polar()

The point being, a circle in some coordinates system is often not a circle in others, unless you use geom_point. You might want to ensure an aspect ratio of 1 with cartesian coordinates.

baptiste
  • 75,767
  • 19
  • 198
  • 294
  • What I want to plot is an importance horizon on a scatter plot. For this jorans solution seems to be the best way. But thanks a lot for your hint as well. – Dominik Jul 28 '11 at 20:30