Interactive UpSet plots for Plotly Dash.
Documentation and live explorer
An UpSet plot visualizes the intersections of many sets. Venn and Euler diagrams become unreadable past three or four sets; UpSet replaces the overlapping circles with:
- a matrix whose columns are sets and whose rows are intersections (filled, connected dots show which sets participate in each intersection),
- set-size bars giving the cardinality of each individual set, and
- intersection-size bars giving the size of each intersection.
This scales to dozens of sets and makes the large intersections obvious at a
glance. dash-upset brings it to Dash as a reusable, themeable,
callback-friendly component.
- Pure Python, MIT-licensed. All UpSet logic (counting modes, sorting, filtering, deviation, theming) composes a Plotly figure in Python. No heavy JavaScript stack, and it renders in notebooks.
- Drop-in Dash component.
UpSetrenders that figure and turns clicks into ordinary component properties, so callbacks use the standardInput(id, property). The compiled React layer ships prebuilt, so installing needs no Node toolchain. - One input, two ways to render. The same data drives a live
UpSetcomponent or a staticcreate_upsetfigure for notebooks and publication export (PNG / SVG / PDF).
pip install dash-upsetconda-forge: A recipe has been prepared and is pending submission to conda-forge/staged-recipes. Once the feedstock is live,
conda install -c conda-forge dash-upsetwill work. Until then, install from PyPI with pip (orpixi add --pypi dash-upsetin a pixi project).
Drop the UpSet component into a Dash layout with a dataframe of boolean
indicator columns (one per set). Clicks surface as component properties your
callbacks read the standard Dash way:
import pandas as pd
from dash import Dash, Input, Output, callback, html
from dash_upset import UpSet
# One row per misclassified test example; 1 = that model got it wrong.
# Overlaps are the shared hard cases; singletons are each model's blind spots.
df = pd.DataFrame(
{
"ResNet": [1, 1, 0, 1, 0, 1],
"ViT": [1, 1, 1, 0, 0, 1],
"XGBoost": [0, 1, 1, 1, 1, 0],
}
)
app = Dash(__name__)
app.layout = html.Div(
[
UpSet(id="errors", data=df, sets=["ResNet", "ViT", "XGBoost"]),
html.Pre(id="out"),
]
)
@callback(Output("out", "children"), Input("errors", "selected_intersection"))
def show(selection):
# {"label": "ResNet & ViT", "sets": ["ResNet", "ViT"], "size": 2}
return str(selection)
if __name__ == "__main__":
app.run(debug=True)selected_intersection updates when an intersection-size bar or a matrix dot
is clicked; selected_sets (a list of set names) updates when a set-size bar
is clicked.
For notebooks, scripts, or static export, create_upset takes the same input
and returns a plain plotly.graph_objects.Figure:
from dash_upset import create_upset, from_counts
fig = create_upset(
from_counts({
"Action": 320, "Comedy": 290, "Drama": 410,
"Action&Comedy": 84, "Action&Drama": 120, "Comedy&Drama": 96,
"Action&Comedy&Drama": 40,
}),
title="Movie genres",
)
fig.show()Element-level data uses the familiar
upsetplot conventions:
from dash_upset import from_contents, from_indicators, from_memberships
from_memberships([("A",), ("A", "B"), ()]) # per-element set names
from_contents({"A": ["x", "y"], "B": ["y", "z"]}) # per-set element ids
from_indicators(boolean_dataframe) # rows = elements, columns = setsfrom_indicators is dataframe-agnostic via
narwhals: pandas, Polars, PyArrow,
cuDF, and Modin frames (or a plain dict of boolean columns) all work, and
dash-upset itself depends on none of those libraries.
Sorting and display are controlled per plot, e.g.
UpSet(data=df, sets=[...], sort_by="degree", sort_sets_by="name", theme="dark");
create_upset accepts the same keywords. The full argument reference lives at
https://phylatech.github.io/dash-upset/reference.html.
Development setup, the docs workflow, and the commit conventions that drive releases are in CONTRIBUTING.md.
- UpSet and the original research by Lex, Gehlenborg, et al. define the technique.
- UpSet 2.0 by the Visualization Design Lab (BSD-3-Clause) is the technique authors' interactive reimplementation.
- UpSet.js by Samuel Gratzl is an interactive JS implementation (AGPLv3 / commercial).
upsetplotby Joel Nothman (BSD-3-Clause) is the established matplotlib-based Python package;dash-upsetmirrors its familiar data-input conventions.
MIT © Evan Roy Rees