A standard Venn diagram divides the plane into all possible regions of equal visual weight, regardless of how many items each region holds. An area-proportional Venn instead scales each region’s area to its size, making the picture itself a quantitative summary.
This vignette covers when to use proportional layouts, how to generate them, and the low-level helpers (solve_2set, solve_3set, circle_intersection_area) that drive them.
library(vennDiagramLab)| Set count | Proportional supported? | Caveats |
|---|---|---|
| 2 | yes (exact) | always achievable with two circles |
| 3 | yes (approximate) | three-circle constraints rarely admit an exact solution; is_approximate = TRUE |
| 4+ | no | use a layered Venn or an UpSet plot instead |
For 4+ sets, analyze(ds, model = "proportional") raises a clear error.
We construct a small toy dataset directly (no file IO):
ds_2 <- methods::new("VennDataset",
set_names = c("A", "B"),
items = list(A = paste0("g", 1:30), B = paste0("g", 21:50)),
item_order = paste0("g", 1:50),
universe_size = 100L,
source_path = NULL,
format = "csv"
)
result_2 <- analyze(ds_2, model = "proportional")
result_2@model
result_2@is_approximateis_approximate is FALSE for 2 sets — the analytical solution always matches the input cardinalities exactly.
svg_2 <- render_venn_svg(result_2)
nchar(svg_2)ds_3 <- methods::new("VennDataset",
set_names = c("A", "B", "C"),
items = list(
A = paste0("g", 1:40),
B = paste0("g", 21:60),
C = paste0("g", 41:80)
),
item_order = paste0("g", 1:80),
universe_size = 100L,
source_path = NULL,
format = "csv"
)
result_3 <- analyze(ds_3, model = "proportional")
result_3@model
result_3@is_approximateFor 3 sets, is_approximate = TRUE — the solver minimizes a residual rather than solving exactly. Inspect result_3@regions to see the actual region sizes the layout achieves.
svg_3 <- render_venn_svg(result_3)
nchar(svg_3)If you only need the geometry (no SVG output), use the solvers directly.
circle_intersection_area(r1, r2, d)The lens-shaped intersection area of two circles with radii r1, r2 and center distance d.
circle_intersection_area(r1 = 1, r2 = 1, d = 1) # ≈ 1.228
circle_intersection_area(r1 = 1, r2 = 1, d = 0) # 1 circle inside the other -> pi*r^2
circle_intersection_area(r1 = 1, r2 = 1, d = 2) # touching at one point -> 0solve_2set(a_only, b_only, ab)Returns r1, r2, d (radii + center distance) for an exact 2-set proportional layout.
geom_2 <- solve_2set(a_only = 20, b_only = 20, ab = 10)
geom_2solve_3set(regions)Returns approximate radii and center positions for a 3-set proportional layout. Input is a named list keyed by bitmask (1..7), where the keys represent exclusive regions: 1=A only, 2=B only, 3=AB, 4=C only, 5=AC, 6=BC, 7=ABC.
geom_3 <- solve_3set(list("1" = 20L, "2" = 20L, "4" = 20L,
"3" = 5L, "5" = 5L, "6" = 5L, "7" = 2L))
str(geom_3)vignette("v01_quickstart") — basic usage if you skipped here directly.vignette("v04_upset_vs_venn_vs_network") — alternatives for 4+ sets.vignette("v08_custom_styling_and_export") — post-render SVG tweaks.