Euler Bar Chart#
The Euler bar chart visualizes overlapping sets. Each bar represents the
union of two sets, drawn as two offset, semi-transparent rectangles whose
physical overlap zone exactly represents the measured intersection between the
sets. Bar height equals set_a + set_b - overlap (the inclusion-exclusion
union).
This is different from a standard stacked bar chart because the segments are not mutually exclusive – they intentionally overlap, and the blended zone where the two rectangles intersect shows the overlap visually.
Like the pebble bar chart, Euler bar charts are rendered as self-contained HTML files with inline CSS and JavaScript (no external dependencies).
Quick start#
from matviz import euler_bar_chart
categories = [
{"name": "nyc", "label": "NYC",
"set_a": 4, "set_b": 1905, "overlap": 4},
{"name": "bos", "label": "Boston",
"set_a": 12, "set_b": 340, "overlap": 8},
{"name": "cam", "label": "Cambridge",
"set_a": 3, "set_b": 120, "overlap": 2},
]
euler_bar_chart(
categories,
"overlap.html",
title="City Reports",
subtitle="Filed vs Total reports by city",
set_a_label="Filed",
set_b_label="Total",
overlap_label="Both",
)
Open overlap.html in a browser to see the chart.
How it works#
Each bar has two semi-transparent rectangles drawn with a horizontal offset:
Set A (left-aligned): height proportional to
set_a, starting at the baseline.Set B (offset right): height proportional to
set_b, starting atset_a - overlapfrom the baseline.
Because set B starts partway up set A, the physical overlap of the two
rectangles equals the measured overlap. Both rectangles use
mix-blend-mode: multiply so the intersection zone blends visually.
The total bar height is the union: set_a + set_b - overlap.
Category data#
Each category dict should have:
Key |
Type |
Description |
|---|---|---|
|
str |
Internal identifier |
|
str |
Display label under the bar |
|
int/float |
Size of set A |
|
int/float |
Size of set B |
|
int/float |
Size of the intersection |
Key parameters#
Parameter |
Default |
Description |
|---|---|---|
|
|
Display name for set A |
|
|
Display name for set B |
|
|
Display name for the overlap |
|
|
Color for set A rectangles |
|
|
Color for set B rectangles |
|
0.72 |
Opacity for set A |
|
0.62 |
Opacity for set B |
|
80 |
Pixel width of each bar |
|
40 |
Pixels between bars |
|
True |
Sort by union total, largest first |
|
True |
Show union total above each bar |
|
True |
Show data table below chart |
|
False |
Open file in default browser |
Data table#
When show_table=True (the default), a table is rendered below the chart with
columns: Category, Set A, Set B, Overlap, Union. The column headers use
set_a_label and set_b_label.
API reference#
- matviz.euler_bar.euler_bar_chart(categories: Sequence[Dict[str, Any]], output: str | Path | None = None, *, title: str = '', subtitle: str = '', set_a_label: str = 'Set A', set_b_label: str = 'Set B', overlap_label: str = 'Overlap', color_a: str = '#6A9BCC', color_b: str = '#C46686', opacity_a: float = 0.72, opacity_b: float = 0.62, bar_width: int = 80, bar_gap: int = 40, sort_desc: bool = True, show_values: bool = True, show_table: bool = True, font_family: str = 'system-ui, -apple-system, sans-serif', extra_css: str = '', open_browser: bool = False) str[source]#
Generate an Euler bar chart as a self-contained HTML file.
An Euler bar chart visualizes overlapping sets. Each bar represents the union of two sets, drawn as two offset, semi-transparent rectangles whose physical overlap zone matches the measured intersection. Bar height equals set_a + set_b - overlap (the inclusion-exclusion union).
- Parameters:
- categorieslist of dict
Each category dict should have:
name(str): internal identifierlabel(str): display label shown under the barset_a(int or float): size of set Aset_b(int or float): size of set Boverlap(int or float): size of the intersection (must be <= min(set_a, set_b))
- outputstr or Path or None
Path to write the HTML file. If None, the HTML string is returned without writing to disk.
- titlestr
Chart title displayed as a heading.
- subtitlestr
Description line below the title.
- set_a_labelstr
Display name for set A in legend and table. Default
"Set A".- set_b_labelstr
Display name for set B in legend and table. Default
"Set B".- overlap_labelstr
Display name for the overlap in the table. Default
"Overlap".- color_astr
CSS color for set A rectangles. Default
"#6A9BCC"(blue).- color_bstr
CSS color for set B rectangles. Default
"#C46686"(rose).- opacity_afloat
Opacity for set A rectangles (0–1). Default 0.72.
- opacity_bfloat
Opacity for set B rectangles (0–1). Default 0.62.
- bar_widthint
Pixel width of each bar column. Default 80.
- bar_gapint
Pixel gap between adjacent bars. Default 40.
- sort_descbool
Sort categories by union total, largest first. Default True.
- show_valuesbool
Show the union total above each bar. Default True.
- show_tablebool
Render a data table below the chart. Default True.
- font_familystr
CSS font stack.
- extra_cssstr
Extra CSS injected into the page.
- open_browserbool
Open the file in the default browser after writing.
- Returns:
- str
The HTML string. Also written to
outputif provided.
Examples
Basic overlapping-set chart:
>>> categories = [ ... {"name": "nyc", "label": "NYC", ... "set_a": 4, "set_b": 1905, "overlap": 4}, ... {"name": "bos", "label": "Boston", ... "set_a": 12, "set_b": 340, "overlap": 8}, ... {"name": "cam", "label": "Cambridge", ... "set_a": 3, "set_b": 120, "overlap": 2}, ... ] >>> html = euler_bar_chart( ... categories, "overlap.html", ... title="City Reports", ... set_a_label="Filed", ... set_b_label="Total", ... overlap_label="Both", ... )
Without the data table:
>>> euler_bar_chart(categories, show_table=False)