# matplotlib-venn: Venn diagrams whose areas mean something

> matplotlib-venn draws two- and three-circle Venn diagrams for matplotlib where each region's area is proportional to the number of items in it, and it ships a second layout algorithm for the three-circle case that optimises a cost function instead of following a fixed heuristic.

**konstantint/matplotlib-venn** — Area-weighted venn-diagrams for Python/matplotlib

- Repository: https://github.com/konstantint/matplotlib-venn
- Website: https://pypi.org/project/matplotlib-venn/
- Stars: 577 · Forks: 74
- Language: Jupyter Notebook
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/konstantint-matplotlib-venn

## What the library actually computes

matplotlib-venn provides routines for plotting area-weighted two- and three-circle Venn diagrams, and the weighting is the whole point. The functions venn2 and venn2_circles accept as their only required argument a three-element tuple of subset sizes, (Ab, aB, AB), and draw a two-circle diagram with the respective region areas. The library is explicit about what that means in the first example: the region corresponding to A and not B will be three times larger in area than the region corresponding to A and B. That is the difference between this and the decorative Venn diagrams that circulate, where the circle sizes are chosen by eye and the labels are whatever the author felt like. The venn3 and venn3_circles pair takes a seven-element tuple of subset sizes, (Abc, aBc, ABc, abC, AbC, aBC, ABC), and draws the three-circle equivalent.

## Sets, Counters, and the four functions

The package provides four main functions, venn2, venn2_circles, venn3 and venn3_circles, and they differ in what they return. The functions venn2 and venn3 draw the diagrams as a collection of colored patches annotated with text labels, while venn2_circles and venn3_circles draw just the circles, returning the list of matplotlib.patch.Circle objects so you can tune them further. The functions venn2_circles and venn3_circles return that list, while venn2 and venn3 return an object of class VennDiagram, which gives access to the constituent patches, the text elements and, since version 0.7, the information about the centers and radii of the circles. Since version 0.7 you can also pass a tuple of two or three set or Counter objects instead of raw numbers, which is the form most people have the data for, since a Counter is a multi-set.

```python
    from matplotlib_venn import venn2
    venn2(subsets = (3, 2, 1))
```

The three-circle case works the same way, with a set_labels argument for the three set names.

```python
    from matplotlib_venn import venn3
    venn3(subsets = (1, 1, 1, 2, 1, 2, 2), set_labels = ('Set1', 'Set2', 'Set3'))
```

## Editing the finished diagram

The VennDiagram object is designed to be edited after the fact, and the elaborate example in the project overview shows the vocabulary for it. Patches are addressed by their identifier with get_patch_by_id, and labels with get_label_by_id, and both return the artist you can call set_alpha, set_color or set_text on. Circles from venn3_circles are ordinary matplotlib Circle objects, so set_lw and set_ls work on them directly. The example also annotates the diagram with a matplotlib annotate call positioned relative to a label's position, with a rounded box and an arc arrow, and the multi-subplot example shows how to pass an ax argument so several diagrams sit in a grid.

```python
    from matplotlib_venn import venn2, venn2_circles
    figure, axes = plt.subplots(2, 2)
    venn2(subsets={'10': 1, '01': 1, '11': 1}, set_labels = ('A', 'B'), ax=axes[0][0])
    venn2_circles((1, 2, 3), ax=axes[0][1])
    venn3(subsets=(1, 1, 1, 1, 1, 1, 1), set_labels = ('A', 'B', 'C'), ax=axes[1][0])
    venn3_circles({'001': 10, '100': 20, '010': 21, '110': 13, '011': 14}, ax=axes[1][1])
    plt.show()
```

Note that the subset sizes can be given as a dictionary keyed by the bitmask, which is how you specify exactly which region each number belongs to when the default ordering is not what you want.

## Installation, and the shapely extra

The package installs like any other Python package.

```python
    $ python -m pip install matplotlib-venn
```

Since version 1.1.0 the package includes an extra cost based layout algorithm for venn3 diagrams, and that algorithm relies on the shapely package, which is not installed as a default dependency. If you need the new algorithm, or simply have nothing against installing shapely along the way, the documented form is to install the extra.

```python
    $ python -m pip install "matplotlib-venn[shapely]"
```

The project is candid that it is quite probable that shapely will become a required dependency eventually in one of the future versions. The base dependencies are numpy, scipy and matplotlib, with shapely listed as optional, and the package metadata records the same three in install_requires with a shapely entry in extras_require. The build system is plain setuptools, and the setup script reads the version out of the package init file rather than hard coding it, and it defines a custom test command so that python setup.py test invokes pytest over the test modules and the docstrings.

## The part nobody mentions: exact areas are not always possible

The documentation has a section on tuning the diagram layout, and it opens with a constraint that is worth reading before you publish any figure. For a three-circle Venn diagram it is not in general possible to achieve exact correspondence between the required set sizes and region areas. The default layout algorithm aims to correctly represent the relative areas of the full individual sets, and the relative areas of the pairwise intersections of the sets, with the project being careful to distinguish the pairwise intersections such as A&B from the regions A&B&~C, A&~B&C and ~A&B&C on the diagram. Sometimes the result is unsatisfactory and either the area weighting or the layout logic needs to be tuned. That is a geometry problem rather than a library limitation, and the library is honest about it: three circles have six free parameters and you have seven region sizes to satisfy.

## The two ways to change the layout

There are two mechanisms. The first adjusts the area weighting by passing a fixed_subset_sizes argument to the DefaultLayoutAlgorithm, which makes the diagram plotted as if some other call had been made while the displayed numbers stay as you gave them. For the two-circle case and the three-circle case the pattern is the same, importing the algorithm from the relevant layout module.

```python
    from matplotlib_venn.layout.venn3 import DefaultLayoutAlgorithm
    venn3((7,6,5,4,3,2,1), layout_algorithm=DefaultLayoutAlgorithm(fixed_subset_sizes=(1,1,1,1,1,1,1)))
```

The second switches to a different implementation entirely, and for venn3 there is an alternative that lays the circles out by optimising a user-provided cost function. You can use the default cost-based algorithm, or build one with a custom cost function and transform, or weight the seven subsets against each other.

```python
    from matplotlib_venn.layout.venn3 import cost_based
    subset_sizes = (100,200,10000,10,20,3,1)
    venn3(subset_sizes, layout_algorithm=cost_based.LayoutAlgorithm())

    alg = cost_based.LayoutAlgorithm(cost_fn=cost_based.WeightedAggregateCost(weights=(0,0,0,1,1,1,1)))
    venn3(subset_sizes, layout_algorithm=alg)
```

The default pairwise algorithm is, theoretically, a special case of the cost-based method with the pairwise cost function, though the documentation notes that the plot from that route will be close to, but not perfectly equal to, the outcome of the DefaultLayoutAlgorithm.

## Conclusion

matplotlib-venn fits a Python analyst who needs a Venn diagram whose region areas actually correspond to subset sizes, since the library computes circle positions and radii from the numbers rather than drawing decorative circles, and it fits anyone who needs to reach into the finished diagram to move a label or restyle a patch. It does not fit a user who expects an exact area for every one of the seven regions of a three-circle diagram, because the documentation says outright that exact correspondence is not generally achievable and the default layout aims at relative areas of the full sets and of the pairwise intersections instead. It also does not fit someone without shapely who needs the cost-based layout, since that extra is not a default dependency. Before you use it, decide which quantity you care about, the full set areas or the pairwise intersections, and pick the layout algorithm that matches.

## FAQ

### What does matplotlib-venn produce?

Area-weighted two- and three-circle Venn diagrams for matplotlib. The functions venn2 and venn3 draw the diagram as colored patches with text labels and return a VennDiagram object, while venn2_circles and venn3_circles draw only the circles and return the list of matplotlib Circle objects.

### Can matplotlib-venn take sets instead of numbers?

Yes, since version 0.7. The venn2 and venn3 functions accept a tuple of two or three set or Counter objects instead of raw subset sizes, and the counts are computed from them. The three-circle example in the overview builds three sets and passes them with their labels.

### Why is exact area matching not always possible for three circles?

The documentation says it is not in general possible to achieve exact correspondence between the required set sizes and region areas. The default layout algorithm aims to correctly represent the relative areas of the full individual sets and of the pairwise intersections, and the result is sometimes unsatisfactory, so the area weighting or the layout logic needs to be tuned.

### What is the cost-based layout algorithm in matplotlib-venn?

It is an alternative layout for venn3, available since version 1.1.0, that lays the circles out by optimising a user-provided cost function. It needs the optional shapely dependency, so it is installed with the extra, and the default pairwise algorithm is theoretically a special case of it with the pairwise cost function.

## Sources

- [Issues](https://github.com/konstantint/matplotlib-venn/issues)
- [konstantint/matplotlib-venn on GitHub](https://github.com/konstantint/matplotlib-venn)
- [License: MIT](https://github.com/konstantint/matplotlib-venn/blob/master/LICENSE)
- [Project website](https://pypi.org/project/matplotlib-venn/)
- [README](https://github.com/konstantint/matplotlib-venn/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/konstantint-matplotlib-venn
