9

I have checked the other questions in here but I couldn't see this problem. I have a labeling problem. Weird thing is that code is working quite OK for all labels except for one. When I checked the data set (which is something really simple), everything seems quite fine (one column with factor variables, another with numerical).

It is weird because it works OK for some other data with the same structure. However, I tried/checked everything but couldn't solve this issue. Here is the problem:

library(ggplot2)
library(ggrepel)

df = data.frame(
  status = c("Oak", "maple", "walnut", "Pine"),
  value = c( 47.54, 37.70, 11.48, 3.28))

ggplot(df, aes(x = "" , y = value, fill = fct_inorder(status))) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar(theta = "y", start = 0 ) +
  scale_fill_brewer(palette = "Set3", direction = -4) +
  geom_label_repel(aes(label = paste0(value, "%")), size=4, show.legend = F, nudge_x = 1) +
  guides(fill = guide_legend(title = "Status")) +
  theme_void()

One of the labels came up with an issue

It would be great if I have at least a suggestion to try or explanation of this weird behaviour.

Apparently, with the new ggplot2 update they figured the position problem out without giving any extra position data but somehow, If you are unable to use it because of technical limitations, this might help to solve this kind of issues.

DSA
  • 655
  • 5
  • 13
  • I think the problem is that geom_bar is using position = "stack", but geom_text_repel isn't. Adding position = "stack" changes the problem. Probably best to pre-calculate the midpoint of each slice of the pie. – Richard Telford Sep 10 '18 at 13:08
  • @RichardTelford yep that's what I have tried to define for geom_label_repel, but neither that nor geom_text_repel doesn't get the "position". Thanks anyway. – DSA Sep 10 '18 at 13:28
  • Possible duplicate of [ggplot, facet, piechart: placing text in the middle of pie chart slices](https://stackoverflow.com/questions/16184188/ggplot-facet-piechart-placing-text-in-the-middle-of-pie-chart-slices) – Kamil Slowikowski Sep 11 '18 at 14:25

1 Answers1

9

I think the problem is that the geom_bar (or better geom_col) defaults to position = stack whereas geom_text_repel doesn't. Setting geom_text_repel to position= "stack" puts the labels at the end of each section of the pie rather than the midpoint.

It is possible to pre-calculate the positions. The code below works for the data shown, but might not be general as it depends on the order of the rows.

library(ggplot2)
library(ggrepel)

df = data.frame(
  status = c("Oak", "maple", "walnut", "Pine"),
  value = c( 47.54, 37.70, 11.48, 3.28))

df2 <- df %>% 
  mutate(
    cs = rev(cumsum(rev(value))), 
    pos = value/2 + lead(cs, 1),
    pos = if_else(is.na(pos), value/2, pos))

ggplot(df, aes(x = "" , y = value, fill = fct_inorder(status))) +
  geom_col(width = 1) +
  coord_polar(theta = "y", start = 0 ) +
  scale_fill_brewer(palette = "Set3", direction = -4) +
  geom_label_repel(aes(y = pos, label = paste0(value, "%")), data = df2, size=4, show.legend = F, nudge_x = 1) +
  guides(fill = guide_legend(title = "Status")) +
  theme_void()
Richard Telford
  • 9,558
  • 6
  • 38
  • 51
  • Hey, thanks a lot! That's a quick solution for the simple datasets but it doesn't explain why the other code works in some and does not work in this data for example. Also, we are basically here, defining the positions manually and it is not actually really practical if we want to control the positions. Thanks a lot anyways, it is again a very quick solution for the simple subsets. – DSA Sep 10 '18 at 13:31
  • 5
    Just an FYI, one way to get labels on the midpoint of bars without calculating the them manually is to use `position = position_stack(vjust = .5)`. (This doesn't solve the problem here because `position_stack()` and `position_nudge()` can't be used at the same time.) – aosmith Sep 10 '18 at 17:39