Reputation: 15072
I thought I understood aligning text to plots but this one has me stumped. I want to use position_fill()
to show the percentage shares of groups, but include the group counts with geom_text
to indicate that different groups have different numbers of observations. Because some groups have very small shares, I decided to just have the labels be fixed at either end of the plot.
Here is my first attempt, using an example group variable long_sepal
from iris
that is just whether or not the Sepal.Length
is bigger than 5.5.
I make a custom y_label
variable that is either 0 or 1 to map to the y
aesthetic of geom_text
, so that the labels are always at the extremes of the plot.
library(tidyverse)
iris %>%
mutate(long_sepal = Sepal.Length > 5.5) %>%
count(Species, long_sepal) %>%
mutate(y_label = if_else(long_sepal, 0, 1)) %>%
ggplot(aes(x = Species)) +
geom_col(aes(y = n, fill = long_sepal), position = position_fill()) +
geom_text(
mapping = aes(label = n, y = y_label, group = long_sepal),
hjust = 0,
position = position_fill()
) +
coord_flip()
All well and good, but the FALSE
labels are hanging off the edge of the plot. No problem, I'll just change the values of y_label
:
iris %>%
mutate(long_sepal = Sepal.Length > 5.5) %>%
count(Species, long_sepal) %>%
mutate(y_label = if_else(long_sepal, 0, 0.5)) %>% # This has changed
ggplot(aes(x = Species)) +
geom_col(aes(y = n, fill = long_sepal), position = position_fill()) +
geom_text(
mapping = aes(label = n, y = y_label, group = long_sepal),
hjust = 0,
position = position_fill()
) +
coord_flip()
And nothing has changed. Interestingly, it seems to work, sort of, on changing the first value in if_else
but not the second, as below. The left labels will move but don't seem to align with 0.25 as I would expect. Any ideas why? Is my mental model of how geoms work breaking here? I suspect it is something to do with position_fill
but I am not sure.
iris %>%
mutate(long_sepal = Sepal.Length > 5.5) %>%
count(Species, long_sepal) %>%
mutate(y_label = if_else(long_sepal, 0.25, 1)) %>% # Now the text moves, but not where I expect
ggplot(aes(x = Species)) +
geom_col(aes(y = n, fill = long_sepal), position = position_fill()) +
geom_text(
mapping = aes(label = n, y = y_label, group = long_sepal),
hjust = 0,
position = position_fill()
) +
coord_flip()
Created on 2019-03-15 by the reprex package (v0.2.1)
Upvotes: 1
Views: 1568
Reputation: 15072
Using the comments, especially from Axeman, I realised that I can use position_identity()
to get the desired result:
library(tidyverse)
iris %>%
mutate(long_sepal = Sepal.Length > 5.5) %>%
count(Species, long_sepal) %>%
ungroup() %>%
mutate(y_label = if_else(long_sepal, 0.01, 0.99)) %>%
ggplot(aes(x = Species)) +
geom_col(aes(y = n, fill = long_sepal), position = position_fill()) +
geom_text(
mapping = aes(label = n, y = y_label, group = long_sepal),
hjust = "inward",
position = position_identity()
) +
coord_flip()
Created on 2019-03-15 by the reprex package (v0.2.1)
Upvotes: 3