hfgolino/EGAnet

Plot labels, legends and edge sizes in `compare.EGA.plots()`

Closed this issue · 5 comments

Hello,
I have encountered a number of annoying issues while trying to customize visual appearance of the combined plot (composed out of four networks) produced by compare.EGA.plots().

Specifically, I have the following problems:

  1. I can't remove the legends from individual plots via compare.EGA.plots(). legend.position = none does not work, neither as an argument of compare.EGA.plots() nor via + theme()

  2. It appears to me that the edge.size argument changes only the size of edges of the base comparison plot. The networks I am working with were fitted using the EBIC and the TMFG methods and two correlaiton matrices of 11 constructs, one computed using sumscores and another estimated using CFA. CFA-based correlations are considerably stronger, so it's quite natural that edges are wider on the CFA-based network plots, and my initial idea was to make them not that wide (they are really huge! see the bottom-right plot on the attached figure) by scaling the edge width parameter down, but in fact it changed only the edge size for the baseline plot (top left).

  3. It's quite difficult to figure out how to control the size of plot labels (and plot margins as well, because often labels overlap with plots themselves). As far as I understand from the source code of the older version of compare.EGA.plots(), it combines the input plots into a single figure via ggarrange() (I am not however sure about the latest-to-date version since I don't see any direct references to ggarrange() inside its source code, or at least I miss it). I managed to make it behaving more or less how I want by supplying font.label = list() as an argument to compare.EGA.plots(), but I am still not sure that it works exaclty like I think it is working, so it would be great to have more control over the rules governing how the input plots are merged by compare.EGA.plots()

I will be grateful for any comments on what I am doing wrong and suggestions how to reach my goals.

Thanks in advance,
Boris

Estimated networks:
four_networks.zip

Plot itself
p_EGA_dimension_level_US

Code for the figure above

p_EGA <- compare.EGA.plots(fit_ega_sum_EBIC, fit_ega_sum_TMFG,
                  fit_ega_fac_EBIC, fit_ega_fac_TMFG,  
                  base = 1,
                  # plot titles
                  labels = c("Sumscores EBIC", "Sumscores TMFG",
                             "Factors EBIC", "Factors TMFG"),
                  rows = 2, columns = 2,
                  # graphical parameters
                  #plot.args = list(vsize = 4, label.size = 2, 
                                   # edge.size = rep(0.15, 78)),
                  vsize = 6, label.size = 3, 
                  # edge.size = 0.005,
                  font.label = list(size = 8, color = "black", 
                                         face = "bold", family = NULL,
                                         hjust = -1)
) 
  

Session Info

R version 4.1.1 (2021-08-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045)

Matrix products: default

locale:
[1] LC_COLLATE=Russian_Russia.1251  LC_CTYPE=Russian_Russia.1251   
[3] LC_MONETARY=Russian_Russia.1251 LC_NUMERIC=C                   
[5] LC_TIME=Russian_Russia.1251    

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

other attached packages:
 [1] dendextend_1.15.1  ggdendro_0.1.23    ggcorrplot_0.1.3   patchwork_1.1.1   
 [5] ggpubr_0.4.0       psych_2.2.9        EGAnet_2.0.1       gt_0.8.0          
 [9] bootnet_1.5        qgraph_1.9.3       psychonetrics_0.11 factoextra_1.0.7  
[13] corrplot_0.90      tidySEM_0.2.0      OpenMx_2.19.6      forcats_0.5.1     
[17] stringr_1.5.0      dplyr_1.1.0        purrr_1.0.1        readr_2.0.1       
[21] tidyr_1.3.0        tibble_3.1.8       ggplot2_3.4.1      tidyverse_1.3.1   
[25] semTools_0.5-6     semPlot_1.1.2      lavaan_0.6-14      foreign_0.8-81    

loaded via a namespace (and not attached):
  [1] utf8_1.2.3            proto_1.0.0           R.utils_2.12.2       
  [4] tidyselect_1.2.0      lme4_1.1-31           htmlwidgets_1.6.1    
  [7] grid_4.1.1            combinat_0.0-8        munsell_0.5.0        
 [10] codetools_0.2-18      interp_1.1-3          withr_2.5.0          
 [13] colorspace_2.1-0      NetworkToolbox_1.4.2  knitr_1.42           
 [16] rstudioapi_0.14       stats4_4.1.1          ggsignif_0.6.2       
 [19] labeling_0.4.2        mi_1.0                emmeans_1.7.3        
 [22] mnormt_2.1.1          farver_2.1.1          coda_0.19-4          
 [25] vctrs_0.5.2           generics_0.1.3        TH.data_1.1-1        
 [28] xfun_0.37             doParallel_1.0.16     R6_2.5.1             
 [31] GA_3.2.3              arm_1.11-2            smacof_2.1-5         
 [34] reshape_0.8.8         assertthat_0.2.1      scales_1.2.1         
 [37] multcomp_1.4-20       nnet_7.3-16           texreg_1.37.5        
 [40] gtable_0.3.1          weights_1.0.4         sandwich_3.0-1       
 [43] rlang_1.0.6           splines_4.1.1         rstatix_0.7.0        
 [46] wordcloud_2.6         broom_0.7.9           checkmate_2.1.0      
 [49] reshape2_1.4.4        abind_1.4-5           modelr_0.1.8         
 [52] backports_1.4.1       Hmisc_4.8-0           tools_4.1.1          
 [55] statnet.common_4.9.0  ellipsis_0.3.2        RColorBrewer_1.1-3   
 [58] Rsolnp_1.16           proxy_0.4-26          polynom_1.4-0        
 [61] gsubfn_0.7            Rcpp_1.0.10           plyr_1.8.8           
 [64] base64enc_0.1-3       VCA_1.4.5             rockchalk_1.8.144    
 [67] rpart_4.1-15          deldir_1.0-6          viridis_0.6.2        
 [70] pbapply_1.7-0         cowplot_1.1.1         zoo_1.8-9            
 [73] haven_2.4.3           ggrepel_0.9.1         cluster_2.1.2        
 [76] fs_1.6.1              magrittr_2.0.3        sna_2.7-1            
 [79] data.table_1.14.8     openxlsx_4.2.4        reprex_2.0.1         
 [82] truncnorm_1.0-8       mvtnorm_1.1-2         matrixcalc_1.0-5     
 [85] hms_1.1.0             xtable_1.8-4          XML_3.99-0.7         
 [88] rio_0.5.27            jpeg_0.1-10           readxl_1.3.1         
 [91] shape_1.4.6           fastDummies_1.6.3     gridExtra_2.3        
 [94] compiler_4.1.1        ellipse_0.4.2         mice_3.14.0          
 [97] crayon_1.5.2          minqa_1.2.5           R.oo_1.25.0          
[100] htmltools_0.5.4       mgcv_1.8-36           corpcor_1.6.10       
[103] tzdb_0.3.0            Formula_1.2-4         snow_0.4-4           
[106] RcppParallel_5.1.4    lubridate_1.7.10      DBI_1.1.1            
[109] mgm_1.2-13            kutils_1.70           dbplyr_2.1.1         
[112] MASS_7.3-54           boot_1.3-28           IsingSampler_0.2.1   
[115] IsingFit_0.3.1        Matrix_1.3-4          car_3.0-11           
[118] wesanderson_0.3.6     heplots_1.4-2         cli_3.6.0            
[121] optimx_2022-4.30      gdata_2.18.0          quadprog_1.5-8       
[124] R.methodsS3_1.8.2     parallel_4.1.1        igraph_1.4.0         
[127] pkgconfig_2.0.3       sem_3.1-11            numDeriv_2016.8-1.1  
[130] xml2_1.3.2            foreach_1.5.2         pbivnorm_0.6.0       
[133] estimability_1.3      rvest_1.0.1           digest_0.6.31        
[136] cellranger_1.1.0      htmlTable_2.4.1       lisrelToR_0.1.4      
[139] curl_4.3.2            gtools_3.9.4          nloptr_2.0.3         
[142] lifecycle_1.0.3       nlme_3.1-152          glasso_1.11          
[145] jsonlite_1.8.4        network_1.18.1        carData_3.0-4        
[148] viridisLite_0.4.1     fansi_1.0.4           pillar_1.8.1         
[151] GGally_2.1.2          lattice_0.20-44       plotrix_3.8-2        
[154] fastmap_1.1.0         httr_1.4.2            survival_3.2-11      
[157] glue_1.6.2            networktools_1.5.0    zip_2.2.0            
[160] fdrtool_1.2.17        MplusAutomation_1.0.0 candisc_0.8-6        
[163] png_0.1-8             iterators_1.0.14      glmnet_4.1-6         
[166] pander_0.6.4          class_7.3-19          stringi_1.7.12       
[169] nnls_1.4              regsem_1.8.0          latticeExtra_0.6-30  
[172] eigenmodel_1.11       e1071_1.7-8  
  

Hi Hudson,
thank you for your quick and honest response.

I tried to do invidiual plots at the first place but I got stuck with another problem: how to define a common layout for all four. There is beautiful averageLayout() from {qgraph} but it seems that it doesn't work with {EGAnet} plots. It's also unclear from documentation how I can extract a layout of a given graph (where it is stored inside the plot object? Which particular element of the list of layers I need to refer to?) and use it for plotting other graphs (can I simpl supply it to the layout = argument?).

Can you please give any advice regarding this?

Best,
Boris

Hi @bssokolov,

I just pushed an update to make many of your desired features more accessible. Here's a script I used on your data to get the plot output below:

# Load packages
library(EGAnet); library(ggplot2); library(ggpubr)

# Set up plots with identical layouts
four_plots <- compare.EGA.plots(
  fit_ega_sum_EBIC, fit_ega_sum_TMFG,
  fit_ega_fac_EBIC, fit_ega_fac_TMFG,  
  base = 1,
  # plot titles
  labels = c("Sumscores EBIC", "Sumscores TMFG",
             "Factors EBIC", "Factors TMFG"),
  rows = 2, columns = 2,
  # graphical parameters
  vsize = 6, label.size = 3,
  edge.size = 3
)

# New output:
# $all = all four plots with defaults
# $individual = each individual plot

# Apply something to each plot
four_plots$individual <- lapply(four_plots$individual, function(x){
  x + theme(legend.position = "none")
})

# Re-do `ggarrange`
updated_plot <- ggarrange(
  plotlist = four_plots$individual,
  ncol = 2, nrow = 2,
  labels = c(
    "Sumscores EBIC", "Sumscores TMFG",
    "Factors EBIC", "Factors TMFG"
  ), hjust = -0.25
)

# Save using `ggsave`
ggsave(
  filename = "four_plots.png",
  plot = updated_plot,
  dpi = 600, width = 8, height = 8
)

In terms of the plot margins, I'm not exactly sure what can be done here (I'm sure there is something). The above code adjusts the centering of the titles so that there is no overlap with the nodes in the network.

four_plots

Hi @AlexChristensen,

Thank you very much for your quick reply and for suggesting a pretty elegant and simple solution! (which makes me feel myself a little stupid because I didn't find it myself and wasted your time instead, for which I apologize). Btw, it seems that margins can be changed in the same way, just by adding plot.margin = ... inside theme().

The solution required adding some additional output for the plots (i.e., $individual), so there was no real way to perform your request without this addition.

Good to know on the margins

Closing as resolved