Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easy way to split one field into n facets #4763

Closed
rjake opened this issue Mar 17, 2022 · 1 comment
Closed

Easy way to split one field into n facets #4763

rjake opened this issue Mar 17, 2022 · 1 comment

Comments

@rjake
Copy link
Contributor

rjake commented Mar 17, 2022

I often create a heatmap that is too long to display on one chart. I have to scratch my head each time to figure out how to break it into columns. I eventually end up with some integer division solution x %/% y like here:

Code
library(tidyverse)
library(scales)

df <- 
  USJudgeRatings |> 
  as_tibble(rownames = "y") |> 
  gather(x, fill, -y) |> 
  mutate(
    x = fct_reorder(x, fill, mean),
    y = fct_reorder(y, fill, sum, .desc = FALSE)
  ) |> 
  print()

# number of columns for plot
n_col <- 2

# separate into columns and keep factor order
plot_prep <- 
  df |> 
  mutate(
    y_order = as.integer(y),
    max_rows = ceiling(n_distinct(y) / n_col),
    facets = (-y_order %/% max_rows) # needs something to facet on, need '-' to keep highest values on left
  ) |> 
  print()

# plot
p <- 
  plot_prep |> 
  ggplot(aes(x, y, fill = fill)) +
  facet_wrap(~facets, ncol = n_col, scales = "free_y") +
  geom_tile(color = "white", size = 0.5) +
  scale_fill_stepsn(breaks = breaks_pretty(6), colours = viridis_pal()(5)) +
  theme(
    strip.background.y = element_blank(),
    strip.text = element_blank(),
    axis.text = element_text(size = 7)
  )

p + theme(aspect.ratio = 1)

# identify aspect ratio
aspect <- 
  plot_prep |> 
  select(x, y) |> 
  summarise_all(n_distinct) |> 
  mutate(ratio = y / x / n_col) |> 
  print() 

p + theme(aspect.ratio = aspect$ratio) # <------ fixed 1:1 size

Could a solution be implemented like one of these?

  • facet_wrap(facets = ~., ncol = 2) -- currently just keeps chart as-is (no facets)
  • a helper function facet_wrap(facets = split_facet(ncol = 2))
  • a new function facet_split(ncol = 2)

Additionally, related to #4584, I often struggle to get the ratios correct.
coord_fixed() throws an error and aspect.ratio affects each panel rather than "unit of y per unit of x".
I included code ☝️ to show how I do it: [# unique y] / [# unique x] / [# of cols]

@hadley
Copy link
Member

hadley commented Mar 23, 2022

This would be a nice feature, but since it could be implemented in a separate package, I think it should be. (That makes much easier to evolve rapidly because it's not strongly connected to the very slow ggplot2 development process). You might consider shopping this idea around the authors of the various ggplot2 extension packages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants