This is a solution that involves setting the aspect ratio of the plots, would that be appropriate? It does depend, to an extent, on what you want to do with these plots. Instead of setting the aspect ratio, you could ggsave() the plots with widths proportionate to the max values of the plots. I defer to others if there is an easier way of achieving this, however.
library(tidyverse)
library(patchwork) # let's me combine plots
# make data
dat = crossing(cat = c("a", "b", "c"),
val = 1:10) |>
filter(if_else(cat == "b" & val > 5, F, T),
if_else(cat == "c" & val > 3, F, T))
# could it be faceted?
ggplot(dat, aes(x = val)) +
geom_density() +
facet_grid( ~ cat, scales = "free_x", space = "free_x") +
scale_x_continuous(breaks = c(0, 2.5, 5, 7.5, 10), limits = c(0,NA))

# separate plots - fix aspect ratio?
ratios = dat |>
group_by(cat) |>
summarise(val = max(val)) |>
mutate(ratio = val / max(val))
myplot = function(dat, c){
dat = filter(dat, cat == c)
r = filter(ratios, cat == c) |> pull(ratio)
ggplot(dat, aes(x = val)) +
geom_density() +
theme(aspect.ratio = 1/r)
}
myplot(dat, "a")

myplot(dat, "b")

myplot(dat, "c")

Created on 2022-01-19 by the reprex package (v2.0.1)