I want to generate a faceted ggplot
with the following properties
- Each facet can have different scale limits (e.g. facet 1 might be taking values from 0-5, while facet 2 might be taking values 100-500) – so I want to be able to see this information
- Each facet has equal x and y axis spacing (i.e. what you’d get if you used
coord_fixed
)
However, ggplot
doesn’t allow you to combine coord_fixed
and facet_wrap(scales = "free")
.
It would be nice if there is a ggplot
solution. It needs to be programmatic, not manual, as my actual application can have varying numbers of facets and scales.
Reprex – an example where I want to compare how well x
values align with y
values.
# data set-up
library(ggplot2)
dat <- data.frame(
group = rep(c("A", "B"), each = 5)
, x = c(1, 2, 3, 4, 5, 100, 200, 300, 400, 700)
, y = c(1, 2, 3, 4, 10, 100, 200, 300, 400, 500)
)
# this has the same aspect ratio on x and y
# but I can't see any detail in group A
ggplot(data = dat) +
geom_point(aes(x = x, y = y)) +
facet_wrap(~ group) +
geom_abline(slope = 1, intercept = 0, colour = "red") +
coord_fixed()
# I can see detail in both groups
# but now the aspect ratios are off
ggplot(data = dat) +
geom_point(aes(x = x, y = y)) +
facet_wrap(~ group, scales = "free") +
geom_abline(slope = 1, intercept = 0, colour = "red")
# manual option - this is the kind of thing I want
# but I don't actually want to have to code this manually
library(patchwork)
g1 <- ggplot(data = dat[dat$group == "A",],) +
geom_point(aes(x = x, y = y)) +
geom_abline(slope = 1, intercept = 0, colour = "red") +
labs(title = "A") +
coord_fixed()
g2 <- ggplot(data = dat[dat$group == "B",],) +
geom_point(aes(x = x, y = y)) +
geom_abline(slope = 1, intercept = 0, colour = "red") +
labs(title = "B") +
coord_fixed()
g1 + g2
You can do it with facetted_pos_scales
function from ggh4x
package.
# data set-up
library(tidyverse)
library(ggh4x)
#>
#> Attaching package: 'ggh4x'
#> The following object is masked from 'package:ggplot2':
#>
#> guide_axis_logticks
dat <- data.frame(
group = rep(c("A", "B"), each = 5)
, x = c(1, 2, 3, 4, 5, 100, 200, 300, 400, 700)
, y = c(1, 2, 3, 4, 10, 100, 200, 300, 400, 500)
)
# Find common limits
df.lims = dat %>%
summarise(lims = list(c(lo = min(union(x, y)), hi = max(union(x, y)))), .by = group)
lims_list = df.lims$lims %>% setNames(df.lims$group)
scale_x_list = lapply(lims_list, function(x) scale_x_continuous(limits = x))
scale_y_list = lapply(lims_list, function(x) scale_y_continuous(limits = x))
# Plot
p = ggplot(data = dat) +
geom_point(aes(x = x, y = y)) +
facet_wrap(~ group, scales = "free") +
geom_abline(slope = 1, intercept = 0, colour = "red")
p + facetted_pos_scales(x = scale_x_list, y = scale_y_list)
Created on 2024-12-19 with reprex v2.0.2