rggplot2plotrose-plot

Polar plot in R using ggplot2


I'm trying to plot a simple polar plot in R using ggplot2 and I'm struggled with strange behavior ! Here is my dataset :

wake_loss_per_sector
   sector wake_loss angle
1       1  16.48843    30
2       2  17.59385    60
3       3  19.19244    90
4       4  27.17434   120
5       5  26.13185   150
6       6  10.95055   180
7       7  11.09595   210
8       8  14.24783   240
9       9  15.59619   270
10     10  19.09893   300
11     11  22.63984   330
12     12  15.84240     0

And here how I try to plot it :

ggplot(wake_loss_per_sector, aes(x = angle, y = wake_loss)) +
  geom_col(width = 25, fill = "skyblue", color = "black") +
  coord_polar(start = 0) +
  scale_x_continuous(
    limits = c(0, 360),
    breaks = seq(0, 330, by = 30),
    minor_breaks = NULL
  ) +
  theme_minimal()

When It runs , it generate a warning :

Warning message:
Removed 1 rows containing missing values (`geom_col()`). 

And the plot looks like the following with missing sector 12 (0 degree) :

enter image description here

Any suggestion is highly appreciated !


Solution

  • If all your bars are the same width and evenly spaced, as in this example, it's easier to use a discrete x (theta)--the defaults will work well for you.

    We do need to set clip = "off" in coord_polar() so data going below 0 due to the width of the bar is still plotted. Your data resolution was at 30 and you set the width to 25, so for the discrete equivalent where the data resolution is 1 I set the width to 25 / 30.

    ggplot(df, aes(x = factor(angle), y = wake_loss)) +
      geom_col(fill = "skyblue", color = "black", width = 25 / 30) +
      coord_polar(start = -.25, clip = "off") +
      theme_minimal()
    

    enter image description here

    However, if you do need the continuous scale and you want to specify the width in data coordinates, you'll need to adjust the axis to account for the width of the bar centered at 0 to have half the width below 0. But to keep 0 at the top, you'll need to adjust the starting angle accordingly, in radians. It's a little obnoxious...

    w = 25
    ggplot(df, aes(x = angle, y = wake_loss)) +
      geom_col(fill = "skyblue", color = "black", width = w) +
      coord_polar(clip = "off", start = -w / 2 / 360 * 2 * pi) +
     scale_x_continuous(
        limits = c(-w / 2, 360 - w / 2),
        breaks = seq(0, 330, by = 30),
        minor_breaks = NULL
      ) +
      theme_minimal()
    

    enter image description here


    Using this sample data:

    df = structure(list(sector = 1:12, wake_loss = c(16.48843, 17.59385, 
    19.19244, 27.17434, 26.13185, 10.95055, 11.09595, 14.24783, 15.59619, 
    19.09893, 22.63984, 15.8424), angle = c(30L, 60L, 90L, 120L, 
    150L, 180L, 210L, 240L, 270L, 300L, 330L, 0L)), class = "data.frame", row.names = c("1", 
    "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))