patchwork icon indicating copy to clipboard operation
patchwork copied to clipboard

Error in valid.viewport: 'x', 'y', 'width', and 'height' must all be units of length 1

Open chrarnold opened this issue 4 years ago • 6 comments

Hi, with R 3.6 I get the following error when plotting two ggplots for patchwork 1.1.1:

`g1 | g2

Error in valid.viewport(x, y, width, height, just, gp, clip, xscale, yscale, : 'x', 'y', 'width', and 'height' must all be units of length 1`

Plotting them individually works just fine, just the combination via patchwork does not. For other plots, patchwork works.

I saved both plots in R in a variable and then exported as rds for reproducibility. I zipped them and put them here (uploading here didnt work due to their size): https://www.dropbox.com/s/7xwcddmdcf118h3/patchwork_bug.zip?dl=0

chrarnold avatar Sep 13 '21 15:09 chrarnold

The issue is caused by the first plot: It contains the following line when constructing that reproducibly causes the error: facet_wrap(~ class + r_positive, labeller = labeller(class=freq_class, r_positive = r_positive_label), nrow = 2)

Here, the class refers to a factor with two levels, but the (subset) data contains only one of them, so that the nested facet_wrap works fine with ggplot but doesnt plot the missing category. However, patchwork seems to stumble upon it.

chrarnold avatar Sep 13 '21 17:09 chrarnold

Here a MWE without any other data:

library(tidyverse) library(patchwork) data = tibble::tibble(a = factor(rep("c", 10),levels = c("c", "x")), b = as.factor(c(rep("c", 5), rep("c", 5))), data = rnorm(10)) g1 = ggplot(data, aes(x = data)) + geom_density() + facet_wrap(~a + b)

g1 | ggplot() + theme_void()

chrarnold avatar Sep 13 '21 17:09 chrarnold

Is there any chance to fix this issue soon? Or at least is there any workaround? I need to create a panel of histograms with density curves, for which I need to iterate through the histograms and apply some simple formula (ggplot2 disallow me to set binwidth in aes() of the geom_histogram).

Yes, I do understand that this is caused by the faceting command, but I like the nicely formatted header per each panel. If I skip this, I will need to manually set the title for each graph and it will be visually inconsistent with my other ones. I want to mimic the facet_wrap as closely as possible.

graphs <- lapply(split(df, list(df$gr1, df$gr2)), function(l) {
    
    fd <- function(x) {
        if(length(x) < 2) return(x/10)
        return(2 * IQR(x, na.rm = TRUE) / (length(x)^(1/3)))
    }
    
    bw <- fd(l$values)

    ggplot(l, aes(x = values)) + 
        facet_wrap(gr1~gr2, scales="free") + 
        geom_histogram(binwidth = bw) + 
        geom_density(aes(y=..count.. * bw), col="blue") + 
        scale_y_continuous(name = "Count", labels = scales::label_comma(accuracy = 1))
})

patchwork::wrap_plots(graphs)

Error in valid.viewport(x, y, width, height, just, gp, clip, xscale, yscale,  : 
  'x', 'y', 'width', and 'height' must all be units of length 1

I wanted to get something like this (without the Y axis title repeated all the time - adjusted manually, here the code is simplified): obraz

Data:


df <- structure(list(gr1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("X", 
"Y", "Z"), class = "factor"), gr2 = structure(c(1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A", 
"B"), class = "factor"), values = c(0.0733973712533799, 0.0697293613698934, 
0.102683448520189, 0.0487695487000943, 0.205106181363666, 0.159035669118421, 
0.110351620037494, 0.0207292925346905, 0.122259659231185, 0.0157066562864822, 
20.6750305935923, 20.0211213093838, 21.5655302430046, 18.4686023060052, 
22.5519338159154, 20.6244801007123, 20.2377072788982, 21.0945842728043, 
21.0837569341144, 18.246170253159, 21.8998013820506, 19.8326093541378, 
22.8584324418656, 18.9870412985307, 20.5554146255417, 19.6616242054847, 
20.0645558668059, 19.977088359113, 20.6064224164085, 18.9858379303864, 
18.99757813783, 18.5918291396209, 20.4995137555724, 20.093389352048, 
20.8483901246638, 19.486806111397, 20.7315744596987, 19.6626914142884, 
21.8591557348387, 20.7655072981502, 20.0088549392756, 19.4422159666346, 
20.2623958487828, 19.4230244300043, 20.4993081847435, 19.9022757785227, 
21.8347008802671, 19.5528243103281, 18.843507077629, 19.5168636944089, 
19.0941453739455, 20.1644101924037, 20.8090812610125, 20.0642456513667, 
18.7417147036915, 21.8379750592094, 18.7956131342515, 19.4596665429375, 
20.1320596410178, 21.4942931079937, 0.966106388027121, 0.996760491050068, 
0.975193757126021, 0.842183554889353, 0.920954022234184, 0.996860243963798, 
0.993181045214292, 0.967845910173358, 0.961024249452834, 0.954234365703608, 
0.979584761329404, 0.933994014564882, 0.974768239386591, 0.823362961711481, 
0.970504933710197, 0.916560359119345, 0.824099224773592, 0.968771424560041, 
0.8209014244639, 0.956891611057596, 1.59537556253065, 2.79151824812018, 
2.42885067042269, 0.477939359567825, 3.15056024101998, 1.82328746022852, 
3.20053735027025, 4.12394583654091, 2.2267019347004, 4.46532087442173, 
3.03136546783142, 2.79784086622059, 5.19422412696102, 2.35544383014069, 
1.14709252312651, 2.76429604393493, 3.11770204196736, 2.16718216814166, 
4.29157857182692, 1.66836580769552, 2.13247155869466, 1.47291489822319, 
2.69524434581336, 2.84919918532188, 4.48684350571098, 1.69811881368391, 
4.20994015555533, 0.86778643464153, 1.09801254522142, 2.53009188487143, 
3.00918287459958, 3.76218716765246, 4.464804861343, 3.81914074504281, 
2.52772302512912, 3.67693672393175, 2.14637396208292, 4.15827785104216, 
3.97983730127652, 2.72993650482531, 2.6948785926973, 3.28505975356107, 
4.75533339676977, 4.00170335669257, 4.2258284874958, 3.5314843016917, 
2.38510941179217, 0.985428402819221, 2.13999393171482, 1.91288694078206, 
0.71561905668791, 0.592393928107901, 0.629527643341252, 0.617854930321108, 
0.87506516435019, 0.791854297242051, 0.332521936957495, 0.841609563654414, 
0.681772775205482, 0.434331063107759, 0.719450173095495, 0.720436836886541, 
0.622322089941363, 0.691545289403829, 0.455973993098666, 0.628320902907914, 
0.457608871032543, 0.721230412894615, 0.417057518846836, 0.69458044037249, 
0.765582755187692, 0.856733333215553, 0.683545967477748, 0.615720048630509, 
0.784685721699002, 0.698676185147128, 0.687591332948515, 0.704901878485528, 
0.64450759836378, 0.690443458144281, 9.56236849193277, 9.08460922991192, 
10.7865281388757, 9.14881285573863, 10.2133640739734, 12.4520771280063, 
8.25882515861193, 9.68657722793995, 9.93427438384345, 10.1890515290523, 
9.62857474580041, 9.2075167992164, 12.2250844490148, 10.6309780789267, 
9.47031397398847, 9.39455907829025, 10.9594544101093, 7.80151480129669, 
10.0172448650331, 9.86399684586222, 9.51269765795659, 11.294471320787, 
11.1168433605057, 11.3584526520635, 8.73321204505872, 9.24776507408582, 
10.307811956138, 10.6395236166973, 9.73090863879671, 11.9321854496828, 
9.91140233650066, 9.376413693499, 9.85269304375105, 10.1705533698205, 
9.95305954421127, 11.3053949849572, 8.19327015169982, 10.8194641845065, 
9.76104444040051, 9.25165956157164, 8.46836333862509, 10.6952969739684, 
9.89765727830814, 10.2705774419072, 9.6939327820413, 10.6231654213364, 
10.4718698926015, 8.61688449391942, 9.98800744560889, 11.7892698968548
)), row.names = c(NA, -210L), class = "data.frame")

EDIT: OK, cowplot made it:

cowplot::plot_grid(plotlist = graphs) obraz

hugesingleton avatar Nov 02 '21 03:11 hugesingleton

I'm not working on patchwork at the moment but PRs are welcome

thomasp85 avatar Nov 02 '21 07:11 thomasp85

Hi, will you continue working on it or development and bugfixes are stalled forever? Just for me to know what to expect in the future and whether or not to integrate your package in my packages, recommending it to others etc. Thanks

chrarnold avatar Dec 16 '21 09:12 chrarnold

I will continue to work on it, but I tackle packages in cycles to avoid context-shifts all the time

thomasp85 avatar Dec 16 '21 10:12 thomasp85

Hi, @thomasp85 First of all, I wanted to thank you very much for patchwork. It's truly awesome package.

Do you have maybe some plans about this issue? Is this something very complex to address? I just wanted to do something very similar to @hugesingleton - to arrange a grid of pre-created of faceted graphs. Only this way I can bypass the limitations of ggplot2 regarding existence of certain parameters in aes().

Is there any chance for this very issue to fix?

Generalized avatar Oct 22 '22 14:10 Generalized

have you tried egg ggarrange ?

library(ggplot2)
library(egg)
#> Loading required package: gridExtra
data = tibble::tibble(a = factor(rep("c", 10),levels = c("c", "x")), b = as.factor(c(rep("c", 5), rep("c", 5))), data = rnorm(10))
g1 = ggplot(data, aes(x = data)) + geom_density() + facet_wrap(~a + b)
egg::ggarrange(g1 , ggplot() + theme_void(),ncol=2)

Created on 2023-06-08 with reprex v2.0.2

smouksassi avatar Jun 08 '23 20:06 smouksassi