Skip to main content

dash-upset

Interactive UpSet plots for Plotly Dash.

Status: early development (pre-1.0). The data model, the figure factory (create_upset), and the interactive UpSet Dash component with click-selection callback properties are implemented and tested; see the roadmap for what's next. Not yet published to PyPI or conda-forge. Documentation: https://phylatech.github.io/dash-upset/

What is an UpSet plot?

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 aims to bring this to Dash as a reusable, themeable, callback-friendly component.

Why this exists

There is no first-class UpSet component for Dash, and wrapping the existing JavaScript implementations has real costs: UpSet.js is AGPLv3 (unsuitable for a permissively licensed library), and while UpSet 2.0 is BSD-3-Clause, embedding its React stack would drag a heavy dependency tree into every app and give up notebook rendering and static export.

dash-upset therefore keeps all UpSet logic (data model, modes, sorting, filtering, deviation, theming) in pure Python, composing the figure from Plotly primitives: MIT-clean and notebook-friendly. The UpSet component adds a thin compiled React layer (react-plotly.js) on top of that same figure so clicks surface as ordinary Dash component properties; the build artifacts are committed, so installing and using the package needs no Node toolchain. upset2-react remains the documented fallback engine if Plotly's interaction ceiling is ever reached. See the roadmap for the full analysis and the decision record.

Installation

dash-upset is not published yet. Once released:

# conda-forge (preferred)
conda install -c conda-forge dash-upset

# or pip
pip install dash-upset

Quick start

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.

Just the figure

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 = sets

from_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

This project uses pixi for environment and task management.

pixi install          # create the environment (deps from conda-forge)
pixi run test         # run the test suite
pixi run lint         # ruff lint
pixi run format       # ruff format

The compiled React layer behind the UpSet component (dash_upset_component/) is committed, so none of the above needs Node. To change it, edit src/lib/components/DashUpset.react.js and rebuild:

npm install
pixi run build-component   # webpack bundle + dash-generate-components classes

See CONTRIBUTING.md for the commit conventions that drive releases.

Prior art and credits

  • 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 and the documented candidate engine should this library ever add a JavaScript renderer (see the roadmap).
  • UpSet.js by Samuel Gratzl is an interactive JS implementation (AGPLv3 / commercial).
  • upsetplot by Joel Nothman (BSD-3-Clause) is the established matplotlib-based Python package; dash-upset mirrors its familiar data-input conventions.

License

MIT © Evan Roy Rees

Metadata

Release files for dash-upset 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dash-upset 0.1.0
File Size Uploaded
dash_upset-0.1.0.tar.gz 1.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for dash-upset 0.1.0
File Interpreter ABI Platform
dash_upset-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 3.2 MB

Release files / dash_upset-0.1.0.tar.gz

Download URL dash_upset-0.1.0.tar.gz
Size 1.6 MB
Tags Source
SHA-256 checksum
How to use checksums
2b8a65e8c15ec10f72626047c12826829c283b0ce4f392ded1eb08bacba72252
BLAKE2b-256 checksum
How to use checksums
ef70a8e3ca6371fdbcebcbe82f85c3751eee130b1d380ba6036e6edb16dabff6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 22, 2026.

Transparency log

Release files / dash_upset-0.1.0-py3-none-any.whl

Download URL dash_upset-0.1.0-py3-none-any.whl
Size 1.6 MB
Tags Python 3
SHA-256 checksum
How to use checksums
f95f783c837fc7fe7572a3b3284bbd6595ddf5075c57a0428df2e2d81a6087ad
BLAKE2b-256 checksum
How to use checksums
67149f73c3d35c45fa7e9d49afb802af7d25a14c1962be3c463bdc991b05e2be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page