facet_wrap(nrow) ignored

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

facet_wrap(nrow) ignored

Ivan Calandra-5
Dear useRs,

I have an issue with the argument nrow of ggplot2::facet_wrap().

Let's consider some sample data:
mydf <- data.frame(grp = rep(letters[1:6], each = 15), cat = rep(1:3,
30), var = rnorm(90))

And let's try to plot with 5 rows:
library(ggplot2)
ggplot(data = mydf, aes(x = cat, y = var)) + geom_point() +
facet_wrap(~grp, nrow = 5)
It plots 2 rows and 3 columns rather than 5 rows and 2 columns as wanted.

These plots are as expected:
ggplot(data = mydf, aes(x = cat, y = var)) + geom_point() +
facet_wrap(~grp, nrow = 2)
ggplot(data = mydf, aes(x = cat, y = var)) + geom_point() +
facet_wrap(~grp, nrow = 6)

My guess is that 5 rows is not ideal for 6 facets (5 facets in 1st
column and only 1 facet for 2nd column) so it overrides the value of
nrow. In the case of 2 or 6 rows, the facets are well distributed in the
layout.

The reason why I need 5 rows with 6 facets is that this facet plot is
part of a patchwork and I would like to have the same number of rows for
all facet plots of the patchwork (so that they all align well).

Is there a way to force the number of rows in the facet_wrap()?

Thank you in advance.
Best,
Ivan

--


--
Dr. Ivan Calandra
TraCEr, laboratory for Traceology and Controlled Experiments
MONREPOS Archaeological Research Centre and
Museum for Human Behavioural Evolution
Schloss Monrepos
56567 Neuwied, Germany
+49 (0) 2631 9772-243
https://www.researchgate.net/profile/Ivan_Calandra

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: facet_wrap(nrow) ignored

R help mailing list-2
Dear Ivan,

I don't think it is possible to force a number of rows - but I'm
honestly just guessing.

What you can do is to add an empty plot. Here I use cowplot, but
gridExtra should also work well.

I add an indication of the row number for the plot to the initial
data.frame, and loop over these.

In the first variant, I add an unused factor to the grp which creates an
empty facet. I personally think this looks a little confusing, so in the
second variant, I add a number of empty plots.

HTH
Ulrik

```
mydf <- data.frame(
   grp = rep(letters[1:6], each = 15),
   cat = rep(1:3, 30),
   var = rnorm(90),
   row_num = rep(c(1, 1, 2, 3, 4, 5), each = 15)
)

s_mydf <- split(mydf, mydf$row_num)

plots_mydf <- lapply(s_mydf, function(x){
   # Ensure no unused factors
   x$grp <- droplevels.factor(x$grp)
   if(length(unique(x$grp)) == 1){
     x$grp <- factor(x$grp, levels = c(unique(x$grp), ""))
   }
   ggplot(data = x, aes(x = cat, y = var)) + geom_point() +
     facet_wrap(~grp, drop=FALSE)
})

cowplot::plot_grid(plotlist = plots_mydf, nrow = 5)

# Maybe more elegant output
plots_mydf <- lapply(s_mydf, function(x, ncol = 2){
   # Ensure no unused factors
   x$grp <- droplevels.factor(x$grp)
   x <- split(x, x$grp)

   p <- lapply(x, function(x){
     ggplot(data = x, aes(x = cat, y = var)) + geom_point() +
       facet_wrap(~grp)
   })

   if(length(p) < ncol){
     pe <- rep(list(ggplot() + theme_void()), ncol - length(p))
     p <- c(p, pe)
   }
   cowplot::plot_grid(plotlist = p, ncol = ncol)
})

cowplot::plot_grid(plotlist = plots_mydf, ncol = 1)

# Or if you prefer not to split the plots on the same row
plots_mydf <- lapply(s_mydf, function(x, ncol = 2){

   p <- list(ggplot(data = x, aes(x = cat, y = var)) + geom_point() +
     facet_wrap(~grp))

   if(length(unique(x$grp)) < ncol){
     pe <- rep(list(ggplot() + theme_void()), ncol - length(p))
     p <- c(p, pe)
   }else{
     ncol <- 1
   }
   cowplot::plot_grid(plotlist = p, ncol = ncol)
})

cowplot::plot_grid(plotlist = plots_mydf, ncol = 1)

```

On 2020-09-09 17:30, Ivan Calandra wrote:

> Dear useRs,
>
> I have an issue with the argument nrow of ggplot2::facet_wrap().
>
> Let's consider some sample data:
> mydf <- data.frame(grp = rep(letters[1:6], each = 15), cat = rep(1:3,
> 30), var = rnorm(90))
>
> And let's try to plot with 5 rows:
> library(ggplot2)
> ggplot(data = mydf, aes(x = cat, y = var)) + geom_point() +
> facet_wrap(~grp, nrow = 5)
> It plots 2 rows and 3 columns rather than 5 rows and 2 columns as
> wanted.
>
> These plots are as expected:
> ggplot(data = mydf, aes(x = cat, y = var)) + geom_point() +
> facet_wrap(~grp, nrow = 2)
> ggplot(data = mydf, aes(x = cat, y = var)) + geom_point() +
> facet_wrap(~grp, nrow = 6)
>
> My guess is that 5 rows is not ideal for 6 facets (5 facets in 1st
> column and only 1 facet for 2nd column) so it overrides the value of
> nrow. In the case of 2 or 6 rows, the facets are well distributed in
> the
> layout.
>
> The reason why I need 5 rows with 6 facets is that this facet plot is
> part of a patchwork and I would like to have the same number of rows
> for
> all facet plots of the patchwork (so that they all align well).
>
> Is there a way to force the number of rows in the facet_wrap()?
>
> Thank you in advance.
> Best,
> Ivan
>
> --
>
>
> --
> Dr. Ivan Calandra
> TraCEr, laboratory for Traceology and Controlled Experiments
> MONREPOS Archaeological Research Centre and
> Museum for Human Behavioural Evolution
> Schloss Monrepos
> 56567 Neuwied, Germany
> +49 (0) 2631 9772-243
> https://www.researchgate.net/profile/Ivan_Calandra
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: facet_wrap(nrow) ignored

Ivan Calandra-5
Thank you Ulrik for the suggestions.

I was thinking of a similar approach using a nested patchwork (which
would be easier for me).

It's just a shame that it is not possible to force a number of rows.
It's good that ggplot2 tries to do things in the most "appropriate" way,
but at some point, when the user decides it needs to have 5 rows, then
ggplot2 should listen, potentially issuing a warning like "the number of
rows specified is not appropriate, consider other values instead (e.g. 2)".

Best,
Ivan

PS: our email server is having troubles today, so I have not received
any other R-related emails. Are there few today or is it just me? There
might even be more answers to my question...

--
Dr. Ivan Calandra
TraCEr, laboratory for Traceology and Controlled Experiments
MONREPOS Archaeological Research Centre and
Museum for Human Behavioural Evolution
Schloss Monrepos
56567 Neuwied, Germany
+49 (0) 2631 9772-243
https://www.researchgate.net/profile/Ivan_Calandra

On 10/09/2020 11:54, Ulrik Stervbo wrote:

> Dear Ivan,
>
> I don't think it is possible to force a number of rows - but I'm
> honestly just guessing.
>
> What you can do is to add an empty plot. Here I use cowplot, but
> gridExtra should also work well.
>
> I add an indication of the row number for the plot to the initial
> data.frame, and loop over these.
>
> In the first variant, I add an unused factor to the grp which creates
> an empty facet. I personally think this looks a little confusing, so
> in the second variant, I add a number of empty plots.
>
> HTH
> Ulrik
>
> ```
> mydf <- data.frame(
>   grp = rep(letters[1:6], each = 15),
>   cat = rep(1:3, 30),
>   var = rnorm(90),
>   row_num = rep(c(1, 1, 2, 3, 4, 5), each = 15)
> )
>
> s_mydf <- split(mydf, mydf$row_num)
>
> plots_mydf <- lapply(s_mydf, function(x){
>   # Ensure no unused factors
>   x$grp <- droplevels.factor(x$grp)
>   if(length(unique(x$grp)) == 1){
>     x$grp <- factor(x$grp, levels = c(unique(x$grp), ""))
>   }
>   ggplot(data = x, aes(x = cat, y = var)) + geom_point() +
>     facet_wrap(~grp, drop=FALSE)
> })
>
> cowplot::plot_grid(plotlist = plots_mydf, nrow = 5)
>
> # Maybe more elegant output
> plots_mydf <- lapply(s_mydf, function(x, ncol = 2){
>   # Ensure no unused factors
>   x$grp <- droplevels.factor(x$grp)
>   x <- split(x, x$grp)
>
>   p <- lapply(x, function(x){
>     ggplot(data = x, aes(x = cat, y = var)) + geom_point() +
>       facet_wrap(~grp)
>   })
>
>   if(length(p) < ncol){
>     pe <- rep(list(ggplot() + theme_void()), ncol - length(p))
>     p <- c(p, pe)
>   }
>   cowplot::plot_grid(plotlist = p, ncol = ncol)
> })
>
> cowplot::plot_grid(plotlist = plots_mydf, ncol = 1)
>
> # Or if you prefer not to split the plots on the same row
> plots_mydf <- lapply(s_mydf, function(x, ncol = 2){
>
>   p <- list(ggplot(data = x, aes(x = cat, y = var)) + geom_point() +
>     facet_wrap(~grp))
>
>   if(length(unique(x$grp)) < ncol){
>     pe <- rep(list(ggplot() + theme_void()), ncol - length(p))
>     p <- c(p, pe)
>   }else{
>     ncol <- 1
>   }
>   cowplot::plot_grid(plotlist = p, ncol = ncol)
> })
>
> cowplot::plot_grid(plotlist = plots_mydf, ncol = 1)
>
> ```
>
> On 2020-09-09 17:30, Ivan Calandra wrote:
>> Dear useRs,
>>
>> I have an issue with the argument nrow of ggplot2::facet_wrap().
>>
>> Let's consider some sample data:
>> mydf <- data.frame(grp = rep(letters[1:6], each = 15), cat = rep(1:3,
>> 30), var = rnorm(90))
>>
>> And let's try to plot with 5 rows:
>> library(ggplot2)
>> ggplot(data = mydf, aes(x = cat, y = var)) + geom_point() +
>> facet_wrap(~grp, nrow = 5)
>> It plots 2 rows and 3 columns rather than 5 rows and 2 columns as
>> wanted.
>>
>> These plots are as expected:
>> ggplot(data = mydf, aes(x = cat, y = var)) + geom_point() +
>> facet_wrap(~grp, nrow = 2)
>> ggplot(data = mydf, aes(x = cat, y = var)) + geom_point() +
>> facet_wrap(~grp, nrow = 6)
>>
>> My guess is that 5 rows is not ideal for 6 facets (5 facets in 1st
>> column and only 1 facet for 2nd column) so it overrides the value of
>> nrow. In the case of 2 or 6 rows, the facets are well distributed in the
>> layout.
>>
>> The reason why I need 5 rows with 6 facets is that this facet plot is
>> part of a patchwork and I would like to have the same number of rows for
>> all facet plots of the patchwork (so that they all align well).
>>
>> Is there a way to force the number of rows in the facet_wrap()?
>>
>> Thank you in advance.
>> Best,
>> Ivan
>>
>> --
>>
>>
>> --
>> Dr. Ivan Calandra
>> TraCEr, laboratory for Traceology and Controlled Experiments
>> MONREPOS Archaeological Research Centre and
>> Museum for Human Behavioural Evolution
>> Schloss Monrepos
>> 56567 Neuwied, Germany
>> +49 (0) 2631 9772-243
>> https://www.researchgate.net/profile/Ivan_Calandra
>>
>> ______________________________________________
>> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide
>> http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.