How do I connect the endpoint & startpoint of geom_line in a polar plot (coord_polar)?

1.9k views Asked by At

I'm a bit stuck with getting the endpoint of a line in a polar plot to connect with the startpoint.

My data:

df <- structure(list(ri = c(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360),
                 n = c(329L, 315L, 399L, 700L, 919L, 757L, 656L, 918L, 1117L, 976L, 878L, 803L, 811L, 1072L, 1455L, 1642L, 1891L, 1688L, 1553L, 1841L, 2061L, 2321L, 2498L, 2080L, 1595L, 1080L, 1002L, 953L, 729L, 604L, 538L, 489L, 535L, 455L, 328L, 351L, 329L),
                 d = c(0.008581340149717, 0.00821617673909074, 0.0104071572028483, 0.0182581705313128, 0.0239703695975378, 0.0197449072745768, 0.017110514097916, 0.0239442864967787, 0.0291348235478234, 0.0254571063408018, 0.022900962466418, 0.0209447299094916, 0.0211533947155638, 0.0279610840136675, 0.0379509116043715, 0.0428284514463079, 0.0493231435353035, 0.0440282740812228, 0.0405070554787553, 0.0480189884973526, 0.0537572706643366, 0.0605388768616813, 0.0651555856960275, 0.0542528495787579, 0.0416025457106341, 0.0281697488197397, 0.0261352669605363, 0.0248571950233444, 0.0190145804533243, 0.015754192858447, 0.0140327082083518, 0.0127546362711599, 0.0139544589060748, 0.0118678108453533, 0.00855525704895798, 0.0091551683664154, 0.008581340149717)),
            .Names = c("ri", "n", "d"), row.names = c(NA, 37L), class = c("tbl_df", "tbl", "data.frame"))

My first attempt at making a polar-plot with this code:

ggplot(df, aes(x=ri, y=d)) +
  geom_line() +
  scale_x_continuous(breaks=seq(0,360,10)) +
  coord_polar() +
  theme_bw() +
  theme(panel.grid.minor=element_blank())

enter image description here

This produces more or less what I want. However, I like to have an y-axis that starts at 0. Therefore, I used the following code:

ggplot(df, aes(x=ri, y=d)) +
  geom_line() +
  scale_x_continuous(breaks=seq(0,360,10)) +
  scale_y_continuous(limits=c(0,0.07), breaks=seq(0,0.06,0.01)) +
  coord_polar() +
  theme_bw() +
  theme(panel.grid.minor=element_blank())

Unfortunately, now the line ends at 350 and does not connect with 0/360: enter image description here

Next I tried:

ggplot(df, aes(x=ri, y=d)) +
  geom_polygon(fill=NA, color="black") +
  scale_x_continuous(breaks=seq(0,360,10)) +
  scale_y_continuous(limits=c(0,0.07), breaks=seq(0,0.06,0.01)) +
  coord_polar() +
  theme_bw() +
  theme(panel.grid.minor=element_blank())

This code does connect the endpoint with the startpoint, but also creates a circle: enter image description here

I also tried geom_path, but that gave the same result as geom_polygon. Analysing the problem further, I tried to make a normal plot with:

ggplot(df, aes(x=ri, y=d)) +
  geom_line() +
  scale_x_continuous(expand=c(0,0), breaks=seq(0,360,10)) +
  scale_y_continuous(limits=c(0,0.07), breaks=seq(0,0.06,0.01)) +
  theme_bw() +
  theme(panel.grid.minor=element_blank())

which gives: enter image description here

As you can see, there is a line between 350 and 360. Doing the same with geom_plygon:

ggplot(df, aes(x=ri, y=d)) +
  geom_polygon(fill=NA, color="black") +
  scale_x_continuous(expand=c(0,0), breaks=seq(0,360,10)) +
  scale_y_continuous(limits=c(0,0.07), breaks=seq(0,0.06,0.01)) +
  theme_bw() +
  theme(panel.grid.minor=element_blank())

which results in: enter image description here

Again, using geom_path instead of geom_polygon gives the same result. So, the problem seems to result from setting the limits for the y-axis in combination with coord_polar.

My questions:

  1. How do I connect the endpoint and the startingpoint in a polar-plot with an y-axis starting at 0 when using geom_line in combination with coord_polar?
  2. Or without getting a circle in the middel when using geom_polygon/geom_path in combination with coord_polar?

Note:
The original dataset did not have a row for ri=0. I added this row myself. It is a duplication of the ri=360 row.

2

There are 2 answers

3
Jaap On BEST ANSWER

After some trail and error, I got what I wanted with the following steps:

  1. Removing the row for ri=360 (which is a duplicate of ri=0) with df <- df[df$ri!=360,]

  2. Transforming ri to a factor & adding group=1 to the aes.

  3. Adding start=-pi*1/36 to coord_polar in order to get the 0 at the top of the polar plot

This results in the following ggplot code:

ggplot(df, aes(x=factor(ri), y=d, group=1)) +
  geom_polygon(fill=NA, color="black") +
  scale_y_continuous(limits=c(0,0.07), breaks=seq(0,0.06,0.01)) +
  coord_polar(start=-pi*1/36) +
  theme_bw() +
  theme(panel.grid.minor=element_blank())

The resulting plot:

enter image description here

2
arvi1000 On

It's a side effect of how you have set the limits of the y scale. Using:

ggplot(dat, aes(x=ri, y=d)) +
  geom_line() +
  scale_x_continuous(expand=c(0,0), breaks=seq(0,360,10)) +
  scale_y_continuous(breaks=seq(0,0.06,0.01)) +
  coord_polar() +
  theme_bw() +
  theme(panel.grid.minor=element_blank())

enter image description here

This is odd because values > 0 shouldn't be truncated by ylim(0, 0.07), but there it is...