# hicVennDiagram Vignette: overview

#### Jianhong Ou

#### 23 July 2025

# Introduction

When comparing samples, it is common to perform the task of identifying overlapping loops among two or more sets of genomic interactions. Traditionally, this is achieved through the use of visualizations such as `vennDiagram` or `UpSet` plots. However, it is frequently observed that the total count displayed in these plots does not match the original counts for each individual list. The reason behind this discrepancy is that a single overlap may encompass multiple interactions for one or more samples. This issue is extensively discussed in the realm of overlapping caller for ChIP-Seq peaks.

The hicVennDiagram aims to provide a easy to use tool for overlapping interactions calculation and proper visualization methods. The hicVennDiagram generates plots specifically crafted to eliminate the deceptive visual representation caused by the counts method.

# Quick start

Here is an example using hicVennDiagram with 3 files in `BEDPE` format.

## Installation

First, install hicVennDiagram and other packages required to run the examples.

    library(BiocManager)
    BiocManager::install("hicVennDiagram")

## Load library

    library(hicVennDiagram)
    library(ggplot2)

    # list the BEDPE files
    file_folder <- system.file("extdata",
                               package = "hicVennDiagram",
                               mustWork = TRUE)
    file_list <- dir(file_folder, pattern = ".bedpe", full.names = TRUE)
    names(file_list) <- sub(".bedpe", "", basename(file_list))
    basename(file_list)

    ## [1] "group1.bedpe" "group2.bedpe" "group3.bedpe"

    venn <- vennCount(file_list)
    ## upset plot
    ## temp fix for https://github.com/krassowski/complex-upset/issues/195
    upset_themes_fix <- lapply(ComplexUpset::upset_themes, function(.ele){
        lapply(.ele, function(.e){
            do.call(theme, .e[names(.e) %in% names(formals(theme))])
        })
    })
    upsetPlot(venn,
              themes = upset_themes_fix)

    ## venn plot
    vennPlot(venn)

    ## use browser to adjust the text position, and shape colors.
    browseVenn(vennPlot(venn))

# Details about `vennCount`

The `vennCount` function borrows the power of `InteractionSet:findOverlaps` to calculate the overlaps and then summarizes the results for each category. Users may want to try different combinations of `maxgap` and `minoverlap` parameters to calculate the overlapping loops.

    venn <- vennCount(file_list, maxgap=50000, FUN = max) # by default FUN = min
    upsetPlot(venn, label_all=list(
                              na.rm = TRUE,
                              color = 'black',
                              alpha = .9,
                              label.padding = unit(0.1, "lines")
                          ),
              themes = upset_themes_fix)

# Plot for overlapping peaks output by `ChIPpeakAnno`

    library(ChIPpeakAnno)
    bed <- system.file("extdata", "MACS_output.bed", package="ChIPpeakAnno")
    gr1 <- toGRanges(bed, format="BED", header=FALSE)
    gff <- system.file("extdata", "GFF_peaks.gff", package="ChIPpeakAnno")
    gr2 <- toGRanges(gff, format="GFF", header=FALSE, skip=3)
    ol <- findOverlapsOfPeaks(gr1, gr2)
    overlappingPeaksToVennTable <- function(.ele){
        .venn <- .ele$venn_cnt
        k <- which(colnames(.venn)=="Counts")
        rownames(.venn) <- apply(.venn[, seq.int(k-1)], 1, paste, collapse="")
        colnames(.venn) <- sub("count.", "", colnames(.venn))
        vennTable(combinations=.venn[, seq.int(k-1)],
                  counts=.venn[, k],
                  vennCounts=.venn[, seq.int(ncol(.venn))[-seq.int(k)]])
    }
    venn <- overlappingPeaksToVennTable(ol)
    vennPlot(venn)

    ## or you can simply try vennPlot(vennCount(c(bed, gff)))
    upsetPlot(venn, themes = upset_themes_fix)

    ## change the font size of labels and numbers
    updated_theme <- ComplexUpset::upset_modify_themes(
                  ## get help by vignette('Examples_R', package = 'ComplexUpset')
                  list('intersections_matrix'=
                           ggplot2::theme(
                               ## font size of label: gr1/gr2
                               axis.text.y=ggplot2::element_text(size=24),
                               ## font size of label `group`
                               axis.title.x=ggplot2::element_text(size=24)),
                       'overall_sizes'=
                           ggplot2::theme(
                               ## font size of x-axis 0-200
                               axis.text=ggplot2::element_text(size=12),
                               ## font size of x-label `Set size`
                               axis.title=ggplot2::element_text(size=18)),
                       'Intersection size'=
                           ggplot2::theme(
                               ## font size of y-axis 0-150
                               axis.text=ggplot2::element_text(size=20),
                               ## font size of y-label `Intersection size`
                               axis.title=ggplot2::element_text(size=16)
                           ),
                       'default'=ggplot2::theme_minimal())
                  )
    updated_theme <- lapply(updated_theme, function(.ele){
        lapply(.ele, function(.e){
            do.call(theme, .e[names(.e) %in% names(formals(theme))])
        })
    })
    upsetPlot(venn,
              label_all=list(na.rm = TRUE, color = 'gray30', alpha = .7,
                             label.padding = unit(0.1, "lines"),
                             size = 8 #control the font size of the individual num
                             ),
              base_annotations=list('Intersection size'=
                                        ComplexUpset::intersection_size(
                                            ## font size of counts in the bar-plot
                                            text = list(size=6)
                                            )),
              themes = updated_theme
              )

# GLEAM test

Genomic Loops Enrichment Analysis Method (GLEAM) do enrichment analysis like GREAT (Genomic Regions Enrichment of Annotations Tool) for the interactions.

    pd <- system.file("extdata", package = "hicVennDiagram", mustWork = TRUE)
    fs <- dir(pd, pattern = ".bedpe", full.names = TRUE)
    fs <- fs[!grepl('group1', fs)] # make the test data smaller
    set.seed(123)
    background <- createGIbackground(fs)
    gleamTest(fs, background = background, method = 'binom')

    ##                                         proportions query_events
    ## group2.bedpe_enriched_with_group3.bedpe   0.7517782         5621
    ##                                         overlapping_events expected_events
    ## group2.bedpe_enriched_with_group3.bedpe               2737        4225.745
    ##                                         pvalue
    ## group2.bedpe_enriched_with_group3.bedpe      1

# Session Info

    sessionInfo()

R version 4.5.1 (2025-06-13 ucrt) Platform: x86_64-w64-mingw32/x64 Running under: Windows Server 2022 x64 (build 20348)

Matrix products: default LAPACK version 3.12.1

locale: [1] LC_COLLATE=C
[2] LC_CTYPE=English_United States.utf8
[3] LC_MONETARY=English_United States.utf8 [4] LC_NUMERIC=C
[5] LC_TIME=English_United States.utf8

time zone: America/New_York tzcode source: internal

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

other attached packages: [1] ChIPpeakAnno_3.43.1
[2] ggplot2_3.5.2
[3] TxDb.Hsapiens.UCSC.hg38.knownGene_3.21.0 [4] GenomicFeatures_1.61.5
[5] AnnotationDbi_1.71.0
[6] Biobase_2.69.0
[7] GenomicRanges_1.61.1
[8] Seqinfo_0.99.2
[9] IRanges_2.43.0
[10] S4Vectors_0.47.0
[11] BiocGenerics_0.55.0
[12] generics_0.1.4
[13] hicVennDiagram_1.7.2

loaded via a namespace (and not attached): [1] eulerr_7.0.2 RColorBrewer_1.1-3
[3] jsonlite_2.0.0 magrittr_2.0.3
[5] farver_2.1.2 rmarkdown_2.29
[7] BiocIO_1.19.0 ragg_1.4.0
[9] vctrs_0.6.5 multtest_2.65.0
[11] memoise_2.0.1 Rsamtools_2.25.1
[13] RCurl_1.98-1.17 htmltools_0.5.8.1
[15] S4Arrays_1.9.1 progress_1.2.3
[17] lambda.r_1.2.4 curl_6.4.0
[19] ComplexUpset_1.3.3 SparseArray_1.9.1
[21] sass_0.4.10 bslib_0.9.0
[23] htmlwidgets_1.6.4 plyr_1.8.9
[25] httr2_1.2.1 futile.options_1.0.1
[27] cachem_1.1.0 GenomicAlignments_1.45.1
[29] lifecycle_1.0.4 pkgconfig_2.0.3
[31] Matrix_1.7-3 R6_2.6.1
[33] fastmap_1.2.0 MatrixGenerics_1.21.0
[35] digest_0.6.37 colorspace_2.1-1
[37] patchwork_1.3.1 regioneR_1.41.3
[39] textshaping_1.0.1 RSQLite_2.4.2
[41] filelock_1.0.3 labeling_0.4.3
[43] httr_1.4.7 polyclip_1.10-7
[45] abind_1.4-8 compiler_4.5.1
[47] bit64_4.6.0-1 withr_3.0.2
[49] BiocParallel_1.43.4 DBI_1.2.3
[51] biomaRt_2.65.0 MASS_7.3-65
[53] rappdirs_0.3.3 DelayedArray_0.35.2
[55] rjson_0.2.23 tools_4.5.1
[57] glue_1.8.0 VennDiagram_1.7.3
[59] restfulr_0.0.16 InteractionSet_1.37.1
[61] grid_4.5.1 polylabelr_0.3.0
[63] reshape2_1.4.4 BSgenome_1.77.1
[65] gtable_0.3.6 tidyr_1.3.1
[67] ensembldb_2.33.1 data.table_1.17.8
[69] hms_1.1.3 xml2_1.3.8
[71] XVector_0.49.0 pillar_1.11.0
[73] stringr_1.5.1 splines_4.5.1
[75] dplyr_1.1.4 BiocFileCache_2.99.5
[77] lattice_0.22-7 survival_3.8-3
[79] rtracklayer_1.69.1 bit_4.6.0
[81] universalmotif_1.27.2 tidyselect_1.2.1
[83] RBGL_1.85.0 Biostrings_2.77.2
[85] knitr_1.50 ProtGenerics_1.41.0
[87] SummarizedExperiment_1.39.1 svglite_2.2.1
[89] futile.logger_1.4.3 xfun_0.52
[91] matrixStats_1.5.0 stringi_1.8.7
[93] UCSC.utils_1.5.0 lazyeval_0.2.2
[95] yaml_2.3.10 evaluate_1.0.4
[97] codetools_0.2-20 tibble_3.3.0
[99] BiocManager_1.30.26 graph_1.87.0
[101] cli_3.6.5 systemfonts_1.2.3
[103] jquerylib_0.1.4 dichromat_2.0-0.1
[105] Rcpp_1.1.0 GenomeInfoDb_1.45.9
[107] dbplyr_2.5.0 png_0.1-8
[109] XML_3.99-0.18 parallel_4.5.1
[111] blob_1.2.4 prettyunits_1.2.0
[113] AnnotationFilter_1.33.0 bitops_1.0-9
[115] pwalign_1.5.0 scales_1.4.0
[117] purrr_1.1.0 crayon_1.5.3
[119] BiocStyle_2.37.0 rlang_1.1.6
[121] KEGGREST_1.49.1 formatR_1.14