Interactive UpSet plots built on plotly: explore intersections among multiple sets with rich tooltips, and copy complete intersection details (Intersection, Size, Members, …) with one click in Quarto, R Markdown, and Shiny documents.
upsetly follows the classic UpSet layout of Lex et al. (2014) — set-size bars, intersection-size bars, and a membership dot matrix — and adds JavaScript hooks so that all tooltip text can be synced into a separate text box for copy‑and‑paste.
Install the released version from CRAN:
install.packages("upsetly")
Or the development version from GitHub:
# install.packages("remotes")
# remotes::install_github("Rbunensi/upsetly")
install.packages("upsetly", repos = c('https://rbunensi.r-universe.dev', 'https://cloud.r-project.org'))
Then load:
library(upsetly)
Given a data frame with:
gene), andA_vs_B & B_vs_C, …),upsetly() will:
min_intersection_size.max_n_intersections intersections.A_vs_B & B_vs_C)In HTML output, you can also display the full tooltip text in a separate box which supports copy‑and‑paste.
library(upsetly)
set.seed(1)
df <- data.frame(
gene = paste0("g", 1:100),
A = rbinom(100, 1, 0.3),
B = rbinom(100, 1, 0.4),
C = rbinom(100, 1, 0.2),
stringsAsFactors = FALSE
)
p <- upsetly(
x = df,
set_cols = c("A", "B", "C"),
id_col = "gene",
max_n_intersections = 50,
members_per_line = 10
)
p # interactive plotly widget
This works in a regular RStudio viewer (or browser) as an interactive UpSet plot.
To make the tooltip text (Intersection, Size, Members, etc.) easy to copy, you can add a small HTML element with id members_box and let upsetly() sync to it.
---
title: "upsetly demo"
format: html
---
```{r}
library(upsetly)
```
```{r}
set.seed(1)
df <- data.frame(
gene = paste0("g", 1:100),
A = rbinom(100, 1, 0.3),
B = rbinom(100, 1, 0.4),
C = rbinom(100, 1, 0.2),
stringsAsFactors = FALSE
)
upsetly(
x = df,
set_cols = c("A", "B", "C"),
id_col = "gene",
max_n_intersections = 50,
box_id = "members_box",
members_per_line = 10
)
```
```{=html}
<pre id="members_box" style="
border: 1px solid #ccc;
padding: 8px;
min-height: 120px;
white-space: pre-wrap;
font-family: monospace;
"></pre>
```
In the rendered HTML:
#members_box.#members_box and locked.The content of members_box is pure text, so you can select and copy it easily.
upsetly(
x,
set_cols = NULL,
id_col = NULL,
min_intersection_size = 1,
max_n_intersections = NULL,
point_size = 8,
bar_color_sets = "black",
bar_color_inters = "black",
active_color = "black",
inactive_color = "lightgray",
line_color = "black",
title = "UpSet (plotly)",
height = 500,
width = NULL,
members_per_line = 20,
box_id = NULL
)
x: data frame containing set columns and optional ID column.set_cols: character vector of column names that define sets.id_col: column name for element IDs (e.g. genes). If NULL, a numeric .elem_id is created.min_intersection_size: minimum number of elements for an intersection to be kept.max_n_intersections:
members_per_line: how many member IDs to show per line in the tooltip / text box.box_id: optional HTML element ID used for synchronized, copyable intersection details.point_size: dot size in the dot matrix.If you use upsetly in your research, please cite it as:
Anbunensi (2026). upsetly: Interactive UpSet Plots Using 'plotly'. R package version 0.1.1. https://CRAN.R-project.org/package=upsetly
MIT © 2026 Anbunensi