teunbrand / ggh4x

ggplot extension: options for tailored facets, multiple colourscales and miscellaneous
https://teunbrand.github.io/ggh4x/
Other
563 stars 33 forks source link

feature request / idea: with facet wrap strips being able to position the strips level where we want independently #57

Closed smouksassi closed 2 years ago

smouksassi commented 2 years ago

first a big thank you for the amazing additional features you provides for ggplot2 amazing super useful features ! was thinking about the below

library(ggh4x)
#> Loading required package: ggplot2
library(tidyr)
#> Warning: package 'tidyr' was built under R version 4.1.1
mtcars_long <- gather(mtcars,xvars,xvalues,mpg,hp,vs )
mtcars_long <- gather(mtcars_long,yvars,yvalues,cyl,disp,drat,wt)

ggplot(mtcars_long,aes(xvalues,yvalues))+
  geom_point()+
  facet_grid(yvars~xvars,switch="both",scales = "free")

ggplot(mtcars_long,aes(xvalues,yvalues))+
  geom_point()+
  facet_nested_wrap(yvars~xvars,scales = "free",ncol=6)

Created on 2021-11-09 by the reprex package (v2.0.1)

the facet_grid force how many column and rows we get. the facet_wrap becomes confusing when we have more than one x and y can we for example think about a way to position the strips on "left" and "bottom so they become lie a patchwork of plots ?

maybe something like: ggplot(mtcars_long,aes(xvalues,yvalues))+ geom_point()+ facet_nested_wrap(yvars~xvars,scales = "free",ncol=6, strip.position = c("left","bottom"))

teunbrand commented 2 years ago

Hi Smouksassi,

Thanks for the kind words! I'm pretty open to having more interesting strip/facet layouts, but I'm slightly confused about what layout exactly you're aiming at. Do you think you could roughly sketch something up on paper or on MS paint that illustrates what the intended outcome is?

Best, Teun

smouksassi commented 2 years ago

hacked

maybe like this the axis and strips can repeat or not removed it because it was easier to mock so the strip level one on top become on the left while the level two strip becomes at the bottom of each panel.

teunbrand commented 2 years ago

Ah yes, I see what you mean now! I think it might be possible by implementing a new strip style that works on top of facet_wrap2() (it's hard to see this work with the grid layout), but it will become a little bit fuzzy what should happen if you have an unequal number of panels per top level groups. I think it is a nice idea, but I can't predict when I'll have time to play around with this.

smouksassi commented 2 years ago

thanks ! totally understand that this might not be urgent I just wanted to share the idea here, I really like the various strip and axis options you provide

teunbrand commented 2 years ago

This is turning out to be more of a challenge than I initially assessed it to be. I think I got a reasonable solution for facet_grid() layouts, but struggle to find a robust solution for facet_wrap() layouts. In particular, in the example given in this issue, how should the strips know it can horizontally merge cyl, drat, disp and wt, but should not merge hp, mpg and vs vertically?

Anyway, some progress is made, but there is still some work to be done.

smouksassi commented 2 years ago

thank you for considering this in the above example I was more thinking that we specify a different position for the different levels of strips I don't know the details and how hard it is but really thanks for looking into it.

facet_nested_wrap(yvars~xvars, , strip.position = c("left","bottom")) do we need a separate argument to specify how things would merge currently it is all automatic with the user unable to control what merge and what not the cyl on the left merges because it is being repeated across panel but I am not sure how your code work to decide what to merge ?

teunbrand commented 2 years ago

I was more thinking that we specify a different position for the different levels of strips

Indeed that is how I see it as well. My current idea is that we should be able to specify something along the following line:

facet_grid2(top_level + bottom_level ~ ., strip = strip_split(position = c("left", "bottom")))

Where then "left" applies to top_level and "bottom" applies to bottom_level. I'm guessing I might just be able to resolve the issue outlined before by specifying that bottom_level strips may only be merged if panels aren't belonging to different top_level categories.

I am not sure how your code work to decide what to merge

For nested strips, it is just a run-length encoding for the strip direction, e.g. horizontal when facet_wrap2(strip.position = "top") or 'bottom', and vertical when 'left' or 'right' (both seperately for the grid layout). If strip_nested(bleed = FALSE), facetting variables of the preceding facetting variable are paste0d so that lower level strips don't merge when their upper levels aren't the same.

teunbrand commented 2 years ago

Alright, I think I've resolved the major kinks in the cable. This should now work with the github version:

library(ggh4x)
library(tidyr)

mtcars_long <- gather(mtcars,xvars,xvalues,mpg,hp,vs )
mtcars_long <- gather(mtcars_long,yvars,yvalues,cyl,disp,drat,wt)

ggplot(mtcars_long,aes(xvalues,yvalues))+
  geom_point()+
  facet_nested_wrap(yvars~xvars,scales = "free",ncol=6,
                    strip = strip_split(position = c("left", "bottom")))

Created on 2022-04-02 by the reprex package (v2.0.1)

In the event that anyone plays around with this and happens to come across bugs or inconsistencies, feel free to let me know :)

teunbrand commented 2 years ago

@andhamel I think this might address #62 with your example:

library(ggh4x)

df2 <- data.frame(
  tissue = c("Blood", "Nerve", "Stomach", "Liver", "Blood", "Kidney"),
  qtl = c("e", "s", "e", "e", "s", "s"),
  gene = c("gene1", "gene1", "gene2", "gene2", "gene3", "gene4"),
  value = c(0.4, 0.2, 0.1, 0.9, 0.5, 0.3),
  second_label = c("label1", "label1", "label1","label1", "label2", "label2")
)

ggplot(df2, aes(x=tissue, y=qtl, size=value))+
  geom_point()+
  facet_nested(second_label + gene ~ .,
               strip = strip_split(c("right", "left")))

Created on 2022-04-02 by the reprex package (v2.0.1)

teunbrand commented 2 years ago

This will probably be in next CRAN version. Let's re-open this when there are new issues.