Plotting a bar plot where Y axis reflects percents, how can I "complete" each bar to 100%?
Consider the following plot:
library(ggplot2)
library(tibble)
my_df <- tribble(~step, ~prop,
"a", 1,
"b", 0.8,
"c", 0.55,
"d", 0.2
)
my_df |>
ggplot(aes(x = step,
y = prop)) +
geom_col()

Created on 2023-09-10 with reprex v2.0.2
How can I create a plot that completes each bar to 100% out of it with dashed lines? Something like:

One option would be use a second geom_col to first draw 100% bars, then place your bars on top of it where we have to explicitly set the outline color. Note: One downside, which I did not realize at first, is that the outline of the background bars shouldn't but is visible. A fix would be to set the linewidth and or the bar width as suggested by @jkd and @r2evans in their comments. A second and cleaner option would be to use a geom_path (see below).
library(ggplot2)
library(tibble)
my_df <- tribble(
~step, ~prop,
"a", 1,
"b", 0.8,
"c", 0.55,
"d", 0.2
)
my_df |>
ggplot(aes(
x = step,
y = prop
)) +
geom_col(aes(y = 1), color = "red", linetype = "dashed", fill = NA) +
geom_col(color = "grey35")

IMHO, the cleanest option to achieve the same result would be to use a geom_path which however requires some effort to create an appropriate dataset to draw the paths:
library(ggplot2)
library(tibble)
library(dplyr, warn = FALSE)
make_path <- function(y, width = .9) {
if (y < 1) {
data.frame(
x = width / 2 * c(-1, -1, 1, 1),
y = c(y, 1, 1, y)
)
} else {
data.frame(x = numeric(0), y = numeric(0))
}
}
df_path <- my_df |>
mutate(step = factor(step)) |>
reframe(make_path(prop), .by = step) |>
mutate(x = as.numeric(step) + x)
my_df |>
ggplot(aes(
x = step,
y = prop
)) +
geom_col(color = "grey35") +
geom_path(
data = df_path,
aes(x = x, y = y, group = step),
color = "red", linetype = "dashed"
)

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With