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 #259

Open
rjake opened this issue Apr 4, 2022 · 1 comment
Open

Easy way to split one field into n facets #259

rjake opened this issue Apr 4, 2022 · 1 comment
Labels
feature a feature request or enhancement

Comments

@rjake
Copy link

rjake commented Apr 4, 2022

I often create a heat map 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, 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]

I originally posted in the ggplot2 repo tidyverse/ggplot2#4763 but was directed to work with other package creators who might be able to take this on. I ❤️ ggforce and think it could be a good home for this type of faceting.

@thomasp85
Copy link
Owner

I like the idea but I do unfortunately not have the bandwidth to develop such a thing at the moment. I'll leave it open in case someone else want to take it on and create a PR

@thomasp85 thomasp85 added the feature a feature request or enhancement label Jan 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature a feature request or enhancement
Projects
None yet
Development

No branches or pull requests

2 participants