Generate area-proportional Euler diagrams using numerical optimization. An Euler diagram is a generalization of a Venn diagram, relaxing the criterion that all interactions need to be represented. Diagrams may be fit with ellipses and circles via a wide range of inputs and can be visualized in numerous ways.
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.
install.packages("eulerr")
devtools::install_github("jolars/eulerr")
eulerr is also available as a shiny app hosted at eulerr.co.
library(eulerr)# From Wilkinson 2012fit <- 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] 0.0001957608fit$diagError#> [1] 0.002251973
and plot it
plot(fit)
Please see the introductory vignette for a brief introduction or eulerr under the hood for details.
eulerr is open source software, licensed under GPL-3.
eulerr uses semantic versioning.
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.
eulerr would not be possible without Ben Frederickson’s work on venn.js or Leland Wilkinson’s venneuler.
venn()
is a new function that produces Venn diagrams for up to
5 sets. The interface
is almost identical to euler()
except that a single integer
can also be provided. A new vignette, Venn diagrams with eulerr,
examplifies its use.plot.euler()
when a list of
Euler diagrams is given has been improved. Setting fontsize
or
cex
now results in appropriately sized strips as one would expect.eulergram()
objects from plot.euler()
now have a proper grob name
for the canvas grob, so that extracting information from them is easier.euler()
now correctly says "ellipses"
and not "coefficients".data.frame
or matrix
inputs now work properly
when values are given as numerics. (#42)error_plot()
is a new function that offers diagnostic plots of
fits from euler()
, letting the user visualize the error in the
resulting Euler diagram.euler()
once again uses the residual sums of squares, rather than the
stress metric, as optimization objective, which means that
output is always scaled appropriately to input (#28).plot.euler()
now uses the
polylabelr package to position
labels for the overlaps of the ellipses, which has improved
performance in plotting complicated diagrams considerably and reduced
the amount of code in this package greatly.euler.data.frame()
method (and by proxy the euler.matrix()
method)
can now take matrices with factors in addition to the previously supported
logical and integer (binary) input. The function will dummy code the variables
for the user.plot.euler()
have been made defunct.plants
, to exemplify the list method for euler()
.fruits
, to exemplify the data.frame method for euler()
.euler.data.frame()
gains an argument sep
, which is a character vector
used to separate dummy-coded factors if there are factors or characters in the
input.organisms
, to exemplify the matrix method for euler()
.pain
, to exemplify the table method for euler()
.euler.table()
gains an argument, factor_names
, for specifying
whether the factor names should be included when generating dummy-coded
variables in case the input is a data.frame with character or factor vectors
or if the input is a table with more than two columns or rows.euler.list()
now passes its ellipsis argument along properly. (#33,
thanks, @banfai)plot.euler()
now returns a gTree
object. All of the plotting mechanisms
are now also found in this function and plot.eulergram()
and
print.eulergram()
basically just call grid::grid.draw()
on the result
of plot.euler()
. This change means that functions such as
gridExtra::grid.arrange()
now work as one would intuit on the objects
produced by plot.euler()
.NA
in the resulting
data.frame
of ellipses.GenSA::GenSA()
from
RcppDE::DEoptim()
.plot.euler()
.euler.data.frame()
now works as expected for tibbles (from the tibble
package) when argument by
is used.plot.euler()
has been rewritten completely from scratch, now using
a custom grid-based implementation rather than lattice. As a result,
all panel.*()
functions and label()
have been deprecated as well
as arguments fill_alpha
, auto.key
, fontface
, par.settings
,
default.prepanel
, default.scales
, and panel
. The
method for plotting diagrams has also changed---rather than overlaying
shapes on top of each other, the diagram is now split into separate polygons
using the polyclip package. Instead of relying on semi-transparent fills,
the colors of the fills are now blended in the CIELab color space (#16).eulerr_options()
have been provided in order to set
default graphical parameters for the diagrams.counts
and outer_strips
to plot.euler()
are now defunct.euler()
now always returns ellipse-based parameters
with columns h
, k
, a
, b
, and phi
, regardless of which shape is used.
This item was previously named "coefficients", but it now called
"ellipses" instead and a custom coef.euler()
method has been added to
make cure that coef()
still works.quantities
and labels
arguments of
plot.euler()
now works correctly (#20).GenSA::GenSA()
to
RcppDE::DEoptim()
.stats::nlm()
again.label
is now a proper generic with an appropriate method (label.euler()
).counts
argument in one
of the vignettes.auto.key = TRUE
and labels were
not in alphabetic order. (#15)shape = "ellipse"
in euler()
. This functionality accompanies an overhaul of the
innards of the function.stats::optim(..., method = "L-BFGS-B")
to stats::nlminb()
.GenSA::GenSA()
when the fit from
nlminb()
isn't good enough, by default for 3 sets and ellipses, but
this behavior can be controlled via a new argument control
.diagError
and regionError
metrics have been changed from
diag_error
and region_error
to reflect the original names.label()
function has been added to extract locations for the overlaps
for third party plotting (#10).counts
argument to plot.euler()
and panel.euler.labels()
have
been deprecated in favor of the more appropriate quantities
.fill_opacity
in plot.euler()
that was deprecated in
v2.0.0 has been made
defunct.eulerr()
has been replaced with euler()
(see update 1.1.0) and made
defunct.euler
:
euler.list()
produces diagrams from a list of sample spaces.euler.table()
produces diagrams from a table
object, as long as there
are no dimensions with values greater than 2.plot.euler()
has been rewritten (again) from the ground up to better match
other high-level functions from lattice. This change is intended to be
as smooth as possible and should not make much of a difference to most users.polygon_args
, mar
, and text_args
to plot.euler()
have been
made defunct.plot.euler()
handles conflicting arguments better.eulerr
now use registration.euler()
now allows single sets (#9).plot.euler()
now use a bold fontface by default in order to
distinguish them from the typeface used for counts.key
in plot.euler()
has been deprecated and replaced with
auto.key
. Notice that using key
does not throw a warning since the
argument is used in lattice::xyplot()
(which plot.euler()
relies on).fill_opacity
is softly deprecated and has been replaced with
fill_alpha
for consistency with other lattice functions.border
argument in plot.euler()
works again (#7).eulerr()
and its related methods been deprecated and are being replaced by
euler()
, which takes slightly different input. Notably, the default is
now to provide input in the form of disjoint class combinations, rather
than unions. This is partly to make the function a drop-in replacement for
venneuler::venneuler
.plot.euler()
has been completely revamped, now interfacing xyplot()
from
lattice. As a result, arguments polygon_args
, mar
, and text_args
have been
deprecated.counts
argument to plot.eulerr
, which intersections and
complements with counts from the original set specification (#6).key
argument to plot.eulerr
that prints a legend next to the
diagram.atan2()
from RcppArmadillo.cost
and now forces the function to
use sums of squares, which is more or less equivalent to the cost function
from venneuler
.plot.euler()
now chooses colors adapted to color vision
deficiency (deuteranopia). With increasingly large numbers of sets, this
adaptation is relaxed to make sure that colors are kept visually distinct.euler()
now uses nlm()
instead of optim(method = "Nelder-Mead")
for
its final optimization.print.eulerr
.cost
argument
(currently eulerAPE
or venneuler
).by
argument to
eulerr
. The result is a list of euler diagrams that can be plotted
in a grid arrangement via a new plot method.mar
argument to plot.eulerr
with a default that produces
symmetric margins.stress
statistic from venneuler.print.eulerr
method.