patchwork icon indicating copy to clipboard operation
patchwork copied to clipboard

negative values for plot margins theme not respected?

Open zktuong opened this issue 5 years ago • 3 comments

Hi,

I'm encountering an issue when combining plots with the latest version of patchwork. This was raised in my repo zktuong/ktplots#7 and I found that this was previously working with patchwork_0.0.1 but not in patchwork_1.0.1.

I think the problem is that negative values in theme(plot.margin = unit(c(-0.75, 0, -0.75, 0), "cm")) were not respected somehow? Doesn't seem to a problem with ggplot2 itself and simply downgrading to patchwork_0.0.1 solved it.

Any advice going forward will be greatly appreciated.

The full code of the function(s) is here:

#' Plotting stacked violin plot
#'
## main function
#' @name StackedVlnPlot
#' @param obj single-cell data. can be seurat/summarizedexperiment object
#' @param features genes/features to plot
#' @param pt.size size of dots
#' @param plot.margin to adjust the white space between each plot.
#' @param ... passed to Seurat::VlnPlot
#' @return StackedVlnPlot
#' @source \url{https://divingintogeneticsandgenomics.rbind.io/post/stacked-violin-plot-for-visualizing-single-cell-data-in-seurat/}
#' @examples
#' data(kidneyimmune)
#' features<- c("CD79A", "MS4A1", "CD8A", "CD8B", "LYZ", "LGALS3", "S100A8", "GNLY", "NKG7", "KLRB1", "FCGR3A", "FCER1A", "CST3")
#' StackedVlnPlot(kidneyimmune, features = features) + theme(axis.text.x = element_text(angle = 90, hjust = 1, size = 8))
#' @import ggplot2
#' @import purrr
#' @import patchwork
#' @export
StackedVlnPlot <- function(obj, features,
                          pt.size = 0, 
                          plot.margin = unit(c(-0.75, 0, -0.75, 0), "cm"),
                          ...) {
  requireNamespace('purrr')
  plot_list<- purrr::map(features, function(x) modify_vlnplot(obj = obj,feature = x, ...))
  
  # Add back x-axis title to bottom plot. patchwork is going to support this?
  plot_list[[length(plot_list)]]<- plot_list[[length(plot_list)]] +
    theme(axis.text.x=element_text(), axis.ticks.x = element_line())
  
  # change the y-axis tick to only max value 
  ymaxs<- purrr::map_dbl(plot_list, extract_max)
  plot_list<- purrr::map2(plot_list, ymaxs, function(x,y) x + 
                            scale_y_continuous(breaks = c(y)) + 
                            expand_limits(y = y))
  requireNamespace('patchwork')
  p <- patchwork::wrap_plots(plotlist = plot_list, ncol = 1) ##### this is where i think it's going wrong
  return(p)
}

## remove the x-axis text and tick
#' @name misc
#' @param obj single-cell data. can be seurat/summarizedexperiment object
#' @param feature genes/features to plot
#' @param pt.size size of dots
#' @param plot.margin to adjust the white space between each plot.
#' @param ... passed to Seurat::VlnPlot
#' @export
modify_vlnplot<- function(obj, 
                          feature, 
                          pt.size = 0, 
                          plot.margin = unit(c(-0.75, 0, -0.75, 0), "cm"),
                          ...) {
  p<- Seurat::VlnPlot(obj, features = feature, pt.size = pt.size, ... )  + 
    xlab("") + ylab(feature) + ggtitle("") + 
    theme(legend.position = "none", 
          axis.text.x = element_blank(), 
          axis.ticks.x = element_blank(), 
          axis.title.y = element_text(size = rel(1), angle = 0), 
          axis.text.y = element_text(size = rel(1)), 
          plot.margin = plot.margin ) 
  return(p)
}

## extract the max value of the y axis
#' @name misc
#' @param p value
#' @export
extract_max<- function(p){
  ymax<- max(ggplot_build(p)$layout$panel_scales_y[[1]]$range$range)
  return(ceiling(ymax))
}
> sessionInfo()
R version 3.6.0 (2019-04-26)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS  10.15.5

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

locale:
[1] en_AU.UTF-8/en_AU.UTF-8/en_AU.UTF-8/C/en_AU.UTF-8/en_AU.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] patchwork_0.0.1 ktplots_1.1.6   ggplot2_3.2.1  

loaded via a namespace (and not attached):
  [1] tsne_0.1-3          nlme_3.1-141        bitops_1.0-6        fs_1.3.1            usethis_1.5.1      
  [6] devtools_2.2.2      RcppAnnoy_0.0.14    RColorBrewer_1.1-2  httr_1.4.1          rprojroot_1.3-2    
 [11] sctransform_0.2.0   tools_3.6.0         backports_1.1.5     R6_2.4.1            irlba_2.3.3        
 [16] KernSmooth_2.23-15  uwot_0.1.4          lazyeval_0.2.2      colorspace_1.4-1    npsurv_0.4-0       
 [21] withr_2.1.2         tidyselect_1.0.0    gridExtra_2.3       prettyunits_1.1.1   processx_3.4.2     
 [26] compiler_3.6.0      cli_2.0.1           plotly_4.9.1        desc_1.2.0          labeling_0.3       
 [31] Seurat_3.1.1        caTools_1.17.1.2    scales_1.1.0        lmtest_0.9-37       pbapply_1.4-2      
 [36] ggridges_0.5.1      callr_3.4.2         stringr_1.4.0       digest_0.6.25       R.utils_2.9.0      
 [41] htmltools_0.4.0     pkgconfig_2.0.3     bibtex_0.4.2        sessioninfo_1.1.1   htmlwidgets_1.5.1  
 [46] rlang_0.4.4         farver_2.0.3        zoo_1.8-6           jsonlite_1.6.1      ica_1.0-2          
 [51] gtools_3.8.1        dplyr_0.8.4         R.oo_1.23.0         magrittr_1.5        Matrix_1.2-17      
 [56] Rcpp_1.0.3          munsell_0.5.0       fansi_0.4.1         reticulate_1.13     ape_5.3            
 [61] viridis_0.5.1       lifecycle_0.1.0     R.methodsS3_1.7.1   stringi_1.4.6       gbRd_0.4-11        
 [66] MASS_7.3-51.4       pkgbuild_1.0.6      gplots_3.0.1.1      Rtsne_0.15          plyr_1.8.5         
 [71] grid_3.6.0          parallel_3.6.0      gdata_2.18.0        listenv_0.7.0       ggrepel_0.8.1      
 [76] crayon_1.3.4        lattice_0.20-38     cowplot_1.0.0       splines_3.6.0       SDMTools_1.1-221.1 
 [81] ps_1.3.2            pillar_1.4.3        igraph_1.2.4.1      future.apply_1.3.0  reshape2_1.4.3     
 [86] codetools_0.2-16    pkgload_1.0.2       leiden_0.3.1        glue_1.3.1          lsei_1.2-0         
 [91] metap_1.1           RcppParallel_4.4.4  data.table_1.12.6   remotes_2.1.1       png_0.1-7          
 [96] vctrs_0.2.3         Rdpack_0.11-0       testthat_2.3.1      tidyr_1.0.0         gtable_0.3.0       
[101] RANN_2.6.1          purrr_0.3.3         future_1.15.0       assertthat_0.2.1    rsvd_1.0.2         
[106] survival_2.44-1.1   viridisLite_0.3.0   tibble_2.1.3        memoise_1.1.0       cluster_2.1.0      
[111] globals_0.12.4      fitdistrplus_1.0-14 ellipsis_0.3.0      ROCR_1.0-7 

zktuong avatar Jul 02 '20 17:07 zktuong

A recent bug-fix removed the possibility of having negative margins. I'm pretty sure that negative widths and heights of any kind is not really supported in grid (which resulted in the bug that started all this).

thomasp85 avatar Jul 02 '20 19:07 thomasp85

If it makes a difference, I often find that using negative plot margins is useful for organizing patches. If it is possible to support this feature, I would greatly appreciate it.

jhrcook avatar Oct 12 '20 13:10 jhrcook

I agree with jhrcook - I would also highly appreciate the possibility of negative margins!

AForsthuber avatar Apr 01 '21 19:04 AForsthuber