Lay out area-proportional euler/venn diagrams for any number of sets
Project description
provenny
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6c17dbb9b15f5d3d4eb479eda20c4124917cb8c596a332086641fe6f45aca18
|
|
| MD5 |
59f4f1741a4345f7f414823b2d25044a
|
|
| BLAKE2b-256 |
89d8eb482f57640ae56956516d533c639ac2a8db606c0a0c4f220abb3284a3e0
|
Provenance
The following attestation bundles were made for provenny-0.2.0.tar.gz:
Publisher:
release.yml on hafaio/provenny
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
provenny-0.2.0.tar.gz -
Subject digest:
d6c17dbb9b15f5d3d4eb479eda20c4124917cb8c596a332086641fe6f45aca18 - Sigstore transparency entry: 2188267012
- Sigstore integration time:
-
Permalink:
hafaio/provenny@3803096a1f94642a8821a55003133ee4fb6e17a8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/hafaio
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3803096a1f94642a8821a55003133ee4fb6e17a8 -
Trigger Event:
workflow_dispatch
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2917db7046a389b2443cdd6933370d0357b97e66d6b84bfd347197321c9591a
|
|
| MD5 |
3e4bb886f4e3b4397410ca4f52cf1cd1
|
|
| BLAKE2b-256 |
6f8f226ebd1c8193546bd575c86a3fad1ddae0c9564c5ce2c9d431d9469b32b3
|
Provenance
The following attestation bundles were made for provenny-0.2.0-py3-none-any.whl:
Publisher:
release.yml on hafaio/provenny
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
provenny-0.2.0-py3-none-any.whl -
Subject digest:
a2917db7046a389b2443cdd6933370d0357b97e66d6b84bfd347197321c9591a - Sigstore transparency entry: 2188267025
- Sigstore integration time:
-
Permalink:
hafaio/provenny@3803096a1f94642a8821a55003133ee4fb6e17a8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/hafaio
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3803096a1f94642a8821a55003133ee4fb6e17a8 -
Trigger Event:
workflow_dispatch
-
Statement type: