How can I generate this kind of Polar chart in R Studio?

Hi,
I need to create a chart that looks something like this (where the text applies to the area between the dimensions). I tried basic polar charts (with ggplot) but that doesn't look like this. Any suggestions on how I can try to do that? (I have 8 categories and percentage for each one).

Edit: my goal is to re-create McGrath's circumplex, only as a chart with percentages for each category.

Thanks!

I'm sure there will be a way in ggplot, but plotly definitely is another option

1 Like

There's an example of a coxcomb plot on the ggplot 2 polar coordinates documentation page

1 Like

Going to try both suggestions. Thanks!!

I have an answer for you, because I know that sometimes we have to make things that are not right, because it's not worth the fight to do it the right way. But I still feel it's necessary to point out that using a polar plot like this is extremely hard to visually interpret. Assuming that the lines indicate 10% marks, then something at 100% has 100 times the area of something at 10%.

With that aside, here's what I came up with. Getting the "grid" on top of the graph required making it manually (per this SO answer). The image will work best with some kind of vector output (such as PDF or SVG) to prevent the bits of whitespace that crop up in the version below.

dat <- structure(
  list(
    Category = structure(
      1:8,
      .Label = c(
        "Infrastructure",
        "Taxes",
        "RSE",
        "Distribution",
        "Sales",
        "Operations",
        "Perks",
        "Marketing"
      ),
      class = "factor"
    ),
    Percentage = c(0.4, 0.5, 0.3,
                   0.7, 1, 0.8, 0.3, 0.9)
  ),
  .Names = c("Category", "Percentage"),
  row.names = c(NA,
                8L),
  class = "data.frame"
)

library(ggplot2)

ggplot(data = dat) +
  geom_col(aes(x = Category, fill = Category, y = Percentage),
           width = 1) +
  geom_hline(yintercept = seq(0, 1, by = .1),
             color = "darkgrey",
             size = .5) +
  geom_vline(xintercept = seq(.5, 8.5, by = 1),
             color = "darkgrey",
             size = .5) +
  coord_polar() +
  theme_minimal() +
  labs(x = NULL, y = NULL) +
  theme(axis.text.y = element_blank(),
        legend.position = "none",
        panel.grid = element_blank())

image

5 Likes

Thank you @nick, that's very helpful, and a great comment (on whether I should use it this way in the first place). Actually, some of my data is skewed (where one category is much higher than the others).

It's more visually accurate if you take the square root of the percentages, as that makes the percentages proportional to the area of the slice instead of the radius. However, it removes a good chunk of the visual appeal:

image

2 Likes

While this is acheivable in ggplot as Nick discussed, back when I was really wanting to push the boundaries of polar plots, I ended up doing so in plotrix using base plot strategies. And I thought it might be useful to you if I explained some of my thinking (and tricks)

Because I wanted banded confidence intervals, and selective lines on top, I treated it as a base plot data informed drawing rather than a ggplot data derived figure. Each confidence band is technically a segment going to the centre, overlain from outermost to innermost (and a very innermost segment of white to create the negative space. Then the guidelines were added on top.

The code that produced this is near the bottom of the page at

3 Likes

Worth looking at, @alexeyza, and noting as a good general reference for just this type of thing is Zuguang Gu's bookdown book: Circular Visualization in R

Though the description jumps right to its more complicated examples, the early sections are definitely helpful for this (including Legends, if you're trying to match that exact layout).

5 Likes