I'm using position_stack(reverse = TRUE)
for both the geom_bar
and geom_text
below to align the text with the correct group. It works fine when all factors are included but, when at least one factor is removed, the labels change position (and the plot also changes in width?)
library(ggplot2)
library(dplyr)
library(scales)
dat <- data.frame(
group = factor(
c("A", "B", "C"),
levels = c("A", "B", "C"),
ordered = TRUE
),
value = c(0.7, 0.2, 0.1))
dat %>%
ggplot(aes(x = 1, y = value, fill = group)) +
geom_bar(
stat = "identity",
position = position_stack(reverse = TRUE),
width = 0.6,
show.legend = FALSE
) +
theme_void() +
geom_label(
aes(
x = 0.65,
y = value,
label = percent(value, 1),
fontface = "bold"
),
position = position_stack(reverse = TRUE),
vjust = 1.5,
size = 5,
colour = "white",
show.legend = FALSE
)
dat %>%
filter(group %in% c("B", "C")) %>%
ggplot(aes(x = 1, y = value, fill = group)) +
geom_bar(
stat = "identity",
position = position_stack(reverse = TRUE),
width = 0.6,
show.legend = FALSE
) +
theme_void() +
geom_label(
aes(
x = 0.65,
y = value,
label = percent(value, 1),
fontface = "bold"
),
position = position_stack(reverse = TRUE),
vjust = 1.5,
size = 5,
colour = "white",
show.legend = FALSE
)
sessionInfo()
#> R version 3.6.1 (2019-07-05)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 18362)
#>
#> Matrix products: default
#>
#> locale:
#> [1] LC_COLLATE=English_New Zealand.1252 LC_CTYPE=English_New Zealand.1252
#> [3] LC_MONETARY=English_New Zealand.1252 LC_NUMERIC=C
#> [5] LC_TIME=English_New Zealand.1252
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] scales_1.1.0 dplyr_0.8.5 ggplot2_3.3.0
#>
#> loaded via a namespace (and not attached):
#> [1] Rcpp_1.0.4.6 knitr_1.28 magrittr_1.5 tidyselect_1.0.0
#> [5] munsell_0.5.0 viridisLite_0.3.0 colorspace_1.4-1 R6_2.4.1
#> [9] rlang_0.4.5 stringr_1.4.0 highr_0.8 tools_3.6.1
#> [13] grid_3.6.1 gtable_0.3.0 xfun_0.13 withr_2.2.0
#> [17] htmltools_0.4.0 ellipsis_0.3.0 assertthat_0.2.1 yaml_2.2.1
#> [21] digest_0.6.25 tibble_3.0.1 lifecycle_0.2.0 crayon_1.3.4
#> [25] farver_2.0.3 purrr_0.3.4 vctrs_0.2.4 glue_1.4.0
#> [29] evaluate_0.14 rmarkdown_2.1 labeling_0.3 stringi_1.4.6
#> [33] compiler_3.6.1 pillar_1.4.3 pkgconfig_2.0.3
Created on 2020-04-30 by the reprex package (v0.3.0)
This actually has nothing to do with your factor dropping. ggplot2 doesn't let you use position stack and nudge (which is what you'd ideally like). You can plot the graph and then adjust it afterwards and re-plot.
library(ggplot2)
library(dplyr)
library(scales)
library(grid)
dat <- data.frame(
group = factor(
c("A", "B", "C"),
levels = c("A", "B", "C"),
ordered = TRUE
),
value = c(0.7, 0.2, 0.1))
p1 <- dat %>%
ggplot(aes(x = 1, y = value, fill = reorder(group, value))) +
geom_bar(
stat = "identity",
position = "stack",
show.legend = FALSE
) +
theme_void() +
geom_label(
aes(
y = value,
label = percent(value, 1),
fontface = "bold"
),
position = position_stack(vjust = .5),
size = 5,
colour = "white",
show.legend = FALSE
)+
xlim(c(.5,1.5))
p1 <- ggplot_build(p1)
#change label position
p1$data[[2]]$x <- p1$data[[2]]$x - .5
#rebuild graph
grid.draw(ggplot_gtable(p1))
dev.off()
p2 <- dat %>%
filter(group %in% c("B", "C")) %>%
ggplot(aes(x = 1, y = value, fill = reorder(group, value))) +
geom_bar(
stat = "identity",
position = "stack",
show.legend = FALSE
) +
theme_void() +
geom_label(
aes(
y = value,
label = percent(value, 1),
fontface = "bold"
),
position = position_stack(vjust = .5),
size = 5,
colour = "white",
show.legend = FALSE
)+
xlim(c(.5,1.5))
p2 <- ggplot_build(p2)
#change label position
p2$data[[2]]$x <- p2$data[[2]]$x - .5
#rebuild graph
grid.draw(ggplot_gtable(p2))
#clear graph
dev.off()