Learn R Programming

eulerr

eulerr generates area-proportional Euler diagrams that display set relationships (intersections, unions, and disjoints) with circles or ellipses. Euler diagrams are Venn diagrams without the requirement that all set interactions be present (whether they are empty or not), which means that, depending on input, eulerr sometimes produces Venn diagrams and sometimes not.

With three or more sets intersecting, exact Euler diagrams are often impossible. For such cases eulerr attempts to provide a good approximation by numerically tuning the parameters of the ellipses or circles to minimize the error in the resulting diagram. Residuals and goodness of fit statistics are provided to assess whether the resulting diagram can be trusted.

Installation

Building eulerr from source requires a Rust toolchain. The minimum supported rustc version is listed in the SystemRequirements field of DESCRIPTION (currently rustc >= 1.88.0). If your system Rust is older than that, install or update via rustup before installing the package from source. CRAN binary builds do not need a local Rust toolchain.

CRAN version

install.packages("eulerr")

Development Version

devtools::install_github("jolars/eulerr")

Web App

eulerr is also available as a web app at https://eunoia.bz/app/.

Usage

library(eulerr)

set.seed(26)

# From Wilkinson 2012
fit <- euler(
  c(
    "A" = 4,
    "B" = 6,
    "C" = 3,
    "D" = 2,
    "E" = 7,
    "F" = 3,
    "A&B" = 2,
    "A&F" = 2,
    "B&C" = 2,
    "B&D" = 1,
    "B&F" = 2,
    "C&D" = 1,
    "D&E" = 1,
    "E&F" = 1,
    "A&B&F" = 1,
    "B&C&D" = 1
  ),
  shape = "ellipse"
)

We can inspect the goodness-of-fit metrics diagError and stress for the solution,

fit$stress
#> [1] 1.280319e-19
fit$diagError
#> [1] 6.774157e-11

and plot it

plot(fit)

Please see the introductory vignette for a brief introduction or eulerr under the hood for details.

Eunoia and Its Ecosystem

eulerr is based on Eunoia, which is a Rust library for fitting and visualizing Euler and Venn diagrams. The pure-Rust core powers bindings in several languages, all backed by the same fitting engine:

LanguagePackageInstall
Pythoneunoia (repo)pip install eunoia
JuliaEunoia.jl (repo)] add Eunoia
JavaScript@jolars/eunoia (repo)npm install @jolars/eunoia
Rusteunoia on crates.io (repo)cargo add eunoia

License

eulerr is open source software, licensed under the MIT license.

Versioning

eulerr uses semantic versioning.

Code of Conduct

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Acknowledgements

eulerr would not be possible without Ben Frederickson’s work on venn.js or Leland Wilkinson’s venneuler.

Copy Link

Version

Install

install.packages('eulerr')

Monthly Downloads

10,094

Version

8.1.0

License

MIT + file LICENSE

Issues

Pull Requests

Stars

Forks

Maintainer

Johan Larsson

Last Published

June 30th, 2026

Functions in eulerr (8.1.0)

max_sets_hard_cap

Absolute upper bound on the number of sets that eunoia can represent in a single diagram. Used by the R-side input validator so the cap is not hardcoded.
makeContext.EulerPanel

Set the panel viewport's xscale/yscale at draw time.
measure_tag_native

Measure one tag's combined AABB in the current viewport's native units.
n_sets

Get the number of sets in he input
makeContent.EulerTags

Re-place tags at draw time so resizing the device doesn't clip labels.
mix_colors

Blend (average) colors
measure_tag_sizes

Measure all candidate tag sizes (regions + optional complement) inside a fresh measurement viewport scaled to xlim/ylim.
pain

Pain distribution data
organisms

Organisms
measure_tag

Native-unit AABB of one composite tag (label stacked above quantity, annotation stacked below quantity, separated by padding). The geometry matches what setup_tag() renders at draw time, so the size handed to eunoia agrees with the actual on-screen footprint.
pad_axis_native

Pad an axis range by pt_pad points, converted to native units against a measurement viewport with the supplied scale. Returns the original range unchanged if the conversion isn't finite (e.g. zero range, no device).
polygon_clip_rust

Clip a (possibly multi-polygon) subject path against a single clip polygon. Mirrors the slice of polyclip::polyclip behavior eulerr actually uses at the stripe-pattern site.
place_euler_labels

Place per-region labels using eunoia's place_labels API.
plants

Plants
new_shape_frame

Allocate a fresh $shapes data frame for n_all sets. Rows for empty sets keep NA in every column so downstream plotting can detect them via is.na(shapes$h) regardless of shape kind.
plot.eulergram

Print (plot) Euler diagram
plot.euler

Plot Euler and Venn diagrams
open_measurement_viewport

Open a temporary grid measurement device + viewport.
run_placement_pass

Single placement pass: measure tags, call the Rust FFI, return the placement records and the canvas bbox returned by eunoia.
print.eulerr_venn

Print a summary of a Venn diagram
print.euler

Print a summary of an Euler diagram
replace_list

Replace (refresh) a list
resolve_placement_opts

Merge user-supplied placement options onto the defaults.
setup_complement_tag

Setup the complement-count tag, in the same shape as a region tag so it shares one makeContent.EulerTags() pass.
rescale

Rescale values to new range
setup_geometry

Compute geometries and label locations
residuals.euler

Residuals of euler object
resolve_gap_native

Resolve a gap option to a numeric in native units inside the current measurement viewport. NULL → falls back to padding_native so the visible leader-tip gap matches the spacing between label and quantity. A grid::unit value converts to native; a bare numeric is interpreted as lines (same convention as eulerr_options()$padding).
venn_layout

Canonical (non-proportional) Venn layout for a given shape.
shape_bounding_box

Per-shape bounding box dispatch. Reads the type tag on shapes (rows are assumed to share a tag since a diagram fixes one shape kind), then picks the appropriate width/height calculation. Falls back to the rotated-ellipse formula when the type is unknown so external callers constructing ad-hoc $shapes frames still get a sensible box.
setup_gpar

Setup gpars
setup_tag

Setup grobs for one tag (label + quantity + annotation + leader).
setup_grobs

Grobify Euler objects
venn

Venn diagrams
tally_combinations

Tally set relationships
update_list

Update list with input
split_waypoints

Split a placement's flat leader_waypoints_x / _y / _lengths return triple into a per-label list of list(x = ..., y = ...) coordinate pairs. Each list element has length-lengths[i] x/y vectors (often 0 — straight leaders carry no waypoints).
shapes_to_ellipse_frame

Project the wide $shapes schema back into the legacy 5-column (h, k, a, b, phi) ellipse data frame for circle/ellipse fits. Preserves the row order and row names so back-compat consumers see exactly the shape they used to.