rggplot2rose-plot

Create a 180 degree rose diagram with differents colours for groups?


I am plotting a distribution of angles with the rose.diag function from the circular library. Input data are degrees.

circ <- circular(data2$mean_ang)
summary(circ)
rose.diag(circ, pch = 16, cex = 1, axes = TRUE, shrink = 1, col=3, prop = 2, 
          bins=36, upper=TRUE, ticks=TRUE, units="degrees")

enter image description here

I post a sample of data:

structure(list(sex = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L), .Label = c("F", "Fc", "M"), class = "factor"), area = structure(c(2L, 
2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("AA", "AM", "AR"
), class = "factor"), mean_ang = c(37.3785, 54.1439666666667, 
58.26328, 26.0818202247191, 16.500981981982, 58.7045, 64.6254, 
88.7488, 68.0051315789474, 50.7701449275362, 71.9524307692308, 
29.7501111111111, 21.7672323943662, 14.6700987654321, 15.4569794238683, 
12.7011125, 13.0968235294118, 28.6825, 12.7437857142857, 16.0024827586207, 
21.531, 6.09045454545455, 7.09880503144654, 33.8071123595506, 
40.1566071428571, 34.6079540983607, 18.1940236686391, 26.8186338028169, 
27.2129230769231, 75.331826446281, 92.2394705882353, 38.6603613445378, 
80.2414871794872, 68.7810454545454, 57.3119345238095, 99.8082886597938, 
50.8413857142857, 16.519125, 52.6062, 79.46416875, 55.1253798882682, 
41.7809574468085, 65.9881707317073, 56.9886991869919, 66.7067129186603, 
81.9102918918919, 52.7566941747573, 75.806781512605, 52.1151818181818, 
54.1975875, 65.5264748201439, 47.1095353535354, 47.7130379746835, 
89.4254302325581, 32.5949724770642, 62.4567419354839, 65.1905301204819, 
53.4842941176471, 9.7815641025641, 10.3269556650246, 36.6245238095238, 
35.7347155963303, 40.1823980582524, 29.6765, 30.5416129032258, 
20.003, 40.4984444444444, 82.9355, 35.5801836734694, 8.4906, 
82.3376666666667, 68.5343045977012, 69.924, 76.5723333333333, 
97.1923333333333, 32.8840909090909, 50.603, 31.5014230769231, 
42.2313333333333, 27.7946888888889, 53.2960545454545, 48.8556814814815, 
40.6237714285714, 67.7999126984127, 66.855390625, 99.226275862069, 
102.765611111111, 53.9172142857143, 66.6297692307692, 73.7972580645161
)), row.names = c(NA, -90L), class = c("grouped_df", "tbl_df", 
"tbl", "data.frame"), vars = c("sex", "area"), drop = TRUE, indices = list(
    0:4, 5:12, 13:27, 28:57, 58:65, 66:89), group_sizes = c(5L, 
8L, 15L, 30L, 8L, 24L), biggest_group_size = 30L, labels = structure(list(
    sex = structure(c(1L, 1L, 2L, 2L, 3L, 3L), .Label = c("F", 
    "Fc", "M"), class = "factor"), area = structure(c(2L, 3L, 
    2L, 3L, 2L, 3L), .Label = c("AA", "AM", "AR"), class = "factor")), row.names = c(NA, 
-6L), class = "data.frame", vars = c("sex", "area"), drop = TRUE))

Apparently, the diagram does not match the results found.

I turned all angles positive, previously..

I would like to build a diagram (if possible with ggplot) that shows the frequency density of the angles from 0 to 180 degrees. The calculated maximum angle was 102.77 degrees.

In addition, I would like the colors to differ for the different sexes analyzed and areas.

Something like this:

enter image description here


Solution

  • Although you can do a polar chart in ggplot, you can't easily do a 180-degree polar plot. It is possible only with a bit of hacking. In this example, I have made a full polar plot, shifted it down the page, removed the gridlines, drawn in new gridlines, and created the "slices" from a stacked polar histogram.

    The code isn't pretty, but the end result is quite nice.

    library(ggplot2)
    
    ggplot() + 
      geom_line(aes(x = c(0, 180), y = c(4, 4)), colour = "gray75") +
      geom_line(aes(x = c(0, 180), y = c(8, 8)), colour = "gray75") +
      geom_line(aes(x = c(0, 180), y = c(12, 12)), colour = "gray75") +
      geom_line(aes(x = c(0, 180), y = c(16, 16)), colour = "gray75") +
      geom_line(aes(x = c(0, 180), y = c(20, 20)), colour = "gray75") +
      geom_vline(aes(xintercept = 0:6 * 30), colour = "gray75") +
      geom_histogram(data = data2, aes(x = mean_ang, fill = sex), 
                     position = "stack", colour = "black", binwidth = 15,
                     boundary = 0) + 
      coord_polar(start = 3 * pi / 2) + 
      scale_x_continuous(limits = c(0, 360), breaks = 0:6 * 30) +
      scale_y_continuous(limits = c(0, 20)) +
      theme_bw() + 
      theme(panel.border = element_blank(), 
            legend.margin = margin(unit(c(0, 5.5, 100, 5.5), "pt")),
            axis.title.y = element_text(hjust = 0.75),
            axis.title.x = element_text(vjust = 5),
            plot.margin = margin(unit(c(50, 5.5, -100, 5.5), "pt")),
            panel.grid = element_blank()) +
      labs(title = "Mean degrees by sex", y = "Count")
    

    Created on 2020-05-12 by the reprex package (v0.3.0)