Skip to main content

provenny

build pypi docs

Lay out area-proportional euler/venn diagrams for any number of sets.

Installation

pip install provenny  # or: uv add provenny

Usage

Give the area of each subset by name and get back a layout:

from provenny import proportional_venn

# Area of every subset you care about; omitted subsets are empty.
diagram = proportional_venn({"A": 1.0, "B": 1.0, "AB": 0.4})

diagram.names       # ('A', 'B')
diagram["A"]        # an Ellipse for set A (or the spelled-out diagram.ellipse("A"))

# A zone is a region inside some sets and outside the rest (None if it is empty)
ab = diagram.zone("AB")      # the A & B zone, or None
ab.center                    # (x, y) label point, always inside the zone
ab.area                      # exact realized area
ab.svg_path()                # boundary as a fillable path (see Plotting)

Each key is the collection of set names a subset is inside. For single-character names a bare string is shorthand for its characters. You must use a tuple like ("Apple",) for multi-character names.

Set labels are not limited to strings -- any hashable object works (integers, enum members, frozensets), and the returned Diagram is generic over the label type:

from enum import Enum, auto

class Team(Enum):
    RED = auto()
    BLUE = auto()

diagram = proportional_venn({(Team.RED,): 1.0, (Team.BLUE,): 1.0, (Team.RED, Team.BLUE): 0.4})
diagram.zone({Team.RED, Team.BLUE})

Ellipses fit targets circles cannot. "ellipse" keeps every pairwise overlap a single connected lens -- the mode to reach for when you want ellipses. "optimal" drops that constraint for the lowest area error it can reach, letting a pair overlap in two disconnected lobes. Both stay circular when circles already suffice.

diagram = proportional_venn({"A": 1.0, "B": 1.0, "AB": 0.4}, mode="ellipse")

Plotting

provenny computes the layout and leaves rendering to your plotting library. Indexing a diagram (or the equivalent diagram.ellipse(name)) gives an Ellipse that exports its outline as a path in a few formats, so shapes drop into whatever you already use.

With matplotlib, build a patch from the named parameters (Ellipse wants full axes and degrees, so double the semi-axes and convert the angle) and label the regions:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.patches import Ellipse

diagram = proportional_venn({"A": 1.0, "B": 1.0, "AB": 0.4}, mode="ellipse")
_, axes = plt.subplots()
for name in diagram.names:
    e = diagram[name]
    axes.add_patch(Ellipse(e.center, 2 * e.major, 2 * e.minor, angle=np.degrees(e.angle), alpha=0.4))
for names in ("A", "B", "AB"):
    z = diagram.zone(names)
    if z is not None:
        axes.annotate(names, z.center, ha="center")
axes.set_aspect("equal")
axes.autoscale()

For plotly (or bokeh, altair, raw svg, ...), svg_path() gives a cubic-Bézier path string that fills as a shape:

import plotly.graph_objects as go

figure = go.Figure()
for name in diagram.names:
    figure.add_shape(type="path", path=diagram[name].svg_path(), opacity=0.4)

Both Ellipse and Zone export three ways to access their boundary paths: svg_path() (above), matplotlib_path() (a (vertices, codes) pair for matplotlib.path.Path), and sample(num) (boundary points). So to fill each subregion a different color, path a Zone instead of an Ellipse:

for names, color in zip(("A", "B", "AB"), ("red", "green", "blue")):
    z = diagram.zone(names)
    if z is not None:
        figure.add_shape(type="path", path=z.svg_path(), fillcolor=color)

Raw array interface

Passing a 1-D array of subset areas (indexed by subset bitmask minus one, bit i = set i; for two sets [|A|, |B|, |A & B|]) returns the shapes directly:

import numpy as np

from provenny import proportional_venn_array, zone

shapes = proportional_venn_array(np.array([1.0, 1.0, 0.4]))
# zone takes a boolean mask over the sets (inside[i] == inside set i); None if empty.
zone(shapes, np.array([True, True]))  # the A & B zone: .center, .area, .svg_path()

Metadata

Release files for provenny 0.2.2

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

Source distribution (sdist)

Source distribution for provenny 0.2.2
File Size Uploaded Provenance Actions
provenny-0.2.2.tar.gz 194.7 kB With provenance Details for provenny-0.2.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for provenny 0.2.2
File Interpreter ABI Platform Actions
provenny-0.2.2-py3-none-any.whl Python 3 none any Details for provenny-0.2.2-py3-none-any.whl

Total release size: 232.1 kB

Release files / provenny-0.2.2.tar.gz

Download URL provenny-0.2.2.tar.gz
Size 194.7 kB
Tags Source
SHA-256 checksum
How to use checksums
a0f79e35422afb156edf795d65fd08419f39a033862f72c4734829ed154c80bd
BLAKE2b-256 checksum
How to use checksums
e993e16882c8276484ebfc1cfd1eceb72d301458c54b99104624f1a30ff439f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 18, 2026.

Transparency log

Release files / provenny-0.2.2-py3-none-any.whl

Download URL provenny-0.2.2-py3-none-any.whl
Size 37.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0498c4fcd2224b696dfe6d3c1643ec9ea937c15027193a06aaf592dfdc54880b
BLAKE2b-256 checksum
How to use checksums
0ccd8e828867a304b4c835e0bbb67ac3fe272262246b4993332f612e4be99551
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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 18, 2026.

Transparency log

Security for provenny 0.2.2

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for provenny-0.2.2.tar.gz

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 18, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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