Skip to main content

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

Project description

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()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

provenny-0.2.0.tar.gz (193.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

provenny-0.2.0-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

File details

Details for the file provenny-0.2.0.tar.gz.

File metadata

  • Download URL: provenny-0.2.0.tar.gz
  • Upload date:
  • Size: 193.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for provenny-0.2.0.tar.gz
Algorithm Hash digest
SHA256 d6c17dbb9b15f5d3d4eb479eda20c4124917cb8c596a332086641fe6f45aca18
MD5 59f4f1741a4345f7f414823b2d25044a
BLAKE2b-256 89d8eb482f57640ae56956516d533c639ac2a8db606c0a0c4f220abb3284a3e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for provenny-0.2.0.tar.gz:

Publisher: release.yml on hafaio/provenny

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file provenny-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: provenny-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 36.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for provenny-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a2917db7046a389b2443cdd6933370d0357b97e66d6b84bfd347197321c9591a
MD5 3e4bb886f4e3b4397410ca4f52cf1cd1
BLAKE2b-256 6f8f226ebd1c8193546bd575c86a3fad1ddae0c9564c5ce2c9d431d9469b32b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for provenny-0.2.0-py3-none-any.whl:

Publisher: release.yml on hafaio/provenny

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page