Closed archavan closed 3 weeks ago
I would like to second this (or at least something similar), for an additional use-example while using geom_tile() in order to constrain the rectangular shapes. The ability to combine coord/aspect specifications and free scaling was especially convenient for multi-panel, faceted tile plots, and even further if different aesthetics are desired. Can there somehow be exceptions for discrete axes perhaps?
library(tidyverse) # with ggplot2 v3.3.3
library(gridExtra)
set.seed(1)
df <- expand_grid(x = letters[1:6], y = LETTERS[1:2]) %>%
mutate(w = case_when(x %in% letters[1:2] ~ "1",
x %in% letters[3:6] ~ "2")) %>%
mutate(value = rnorm(6*2))
gg <- ggplot(df) +
geom_tile(aes(x, y, fill = value)) +
facet_grid(cols = vars(w), scales = "free", space = "free") +
scale_fill_distiller(palette="Greens")
A <- gg
A
B <- gg + theme(aspect.ratio = 1)
B
C <- gg + coord_fixed()
C
#Error: coord_fixed doesn't support free scales
#Run `rlang::last_error()` to see where the error occurred.
D <- gg + coord_equal()
D
#Error: coord_fixed doesn't support free scales
#Run `rlang::last_error()` to see where the error occurred.
grid.arrange(A, B)
df2 <- expand_grid(x = letters[17:26], y = LETTERS[1:2]) %>%
mutate(w = case_when(x %in% letters[17:23] ~ "3",
x %in% letters[24:26] ~ "4")) %>%
mutate(value = rnorm(5*4))
gg2 <- ggplot(df2) +
geom_tile(aes(x, y, fill = value)) +
facet_grid(cols = vars(w), scales = "free", space = "free") +
scale_fill_distiller(palette="Blues")
E <- gg2
E
F <- gg2 + theme(aspect.ratio = 1)
F
grid.arrange(A, E, B, F, ncol = 2, widths = c(0.7,1))
Please let me know if anything in this request was unclear.
I'm generally fine with this if it can be implemented in a clean way
Copying @baderstine's comment from https://github.com/tidyverse/ggplot2/issues/3834#issuecomment-1165825262, which describes why the combination of theme(aspect.ratio = )
and facet_grid(space = "free")
was useful. On #3834, we came to the conclusion the combination is probably against the semantics of aspect.ratio
, but this usage (the last example) should be something that ggplot2 should provide if possible. I think the combination of coord_fixed()
and facet_grid(scales = "free, space = "free")
should produce this?
ok, this should help:
devtools::install_version("ggplot2", "3.3.3")
library(ggplot2)
ggplot(dat, aes(y = y, x = var)) +
geom_tile(width = .8, height = .8) +
theme(aspect.ratio = 1) +
facet_grid(cols = vars(vargrp, varunt), drop = T) # , scales="free_x", space="free_x")
Plot 1: has the correct aspect ratio, but it includes every single x category in every facet, regardless of whether a value is actually present:
ggplot(dat, aes(y = y, x = var)) +
geom_tile(width = .8, height = .8) +
# theme(aspect.ratio = 1) +
facet_grid(cols = vars(vargrp, varunt), drop = T, scales="free_x", space="free_x")
Plot 2: drops the irrelevant x categories in each facet, however my tiles are not the shape that i want (square):
my.aspect.ratio = length(unique(dat$y))
# without space = "free_x"
ggplot(dat, aes(y = y, x = var, color=xval)) +
geom_tile(width = .8, height = .8) +
theme(aspect.ratio = my.aspect.ratio) +
facet_grid(cols = vars(vargrp, varunt), drop = T, scales="free_x")
Plot 3: drops irrelevant x categories and each facet's size is constant but the facets with more x categories are now squished... more categories, more squish. :(
# this plot is perfect (in ggplot2 v <=3.3.3), but now I'm not allowed to make it:
# I supply a custom aspect ratio, so that I can change the shape (aspect ratio) of my resulting tiles.
ggplot(dat, aes(y = y, x = var, color=xval)) +
geom_tile(width = .8, height = .8) +
theme(aspect.ratio = my.aspect.ratio) +
facet_grid(cols = vars(vargrp, varunt), drop = T, scales="free_x", space="free_x")
Plot 4: drops irrelevant x categories and allows the size of each x facet to vary based on how many categories are in it, and with a specific aspect ratio applied, i can now make nice little squarish boxes.
Copying @baptiste's comment from #3834 (comment)
not me, @baderstine I believe
Aw, yes... Sorry for the noise.
It makes sense that it’s not possible to mix
facet_grid(..., scales = "free", space = "free")
withcoord_fixed()
in most situations. However, I think that it should be possible and makes sense to allow this when both, x and y, scales are discrete.For example, a use case in this reprex with
ggplot2
version 3.3.4:Here, we have different numbers and levels of factors in x scale, so it’s necessary to use
scales = "free"
andspace = "free"
for efficient use of space.When I make plots like this one, I like to make sure that the breaks on x and y axes are placed equidistantly (so the background grid is made of squares), which would generally be accomplished with
coord_fixed()
but not possible in this case since we are using free scales and space.As of version 3.3.3 of
ggplot2
it was possible to still accomplish this withoutcoord_fixed()
by the (perhaps hacky and off-label) use oftheme(aspect.ratio = 1)
, also pointed out in this SO post. See reprex below with version 3.3.3. This is however no longer possible since this bug was fixed (#4432).It would be great if this can be accomplished legitimately with
coord_fixed()
rather than by using hacks. Based on my admittedly superficial understanding, I think that the use ofcoord_fixed()
when faceting with free scales and space should be legitimate as long as the x and y scales are discrete.Created on 2021-08-12 by the reprex package (v2.0.0)