# eulerr 8.0

This is a major milestone for eulerr. The 8.0.0 release introduces a complete
rewrite of the underlying C++ codebase, now relying instead on the Rust library
[Eunoia](https://eunoia.bz), which is a library I have developed. Here are some
of the highlights this brings:

- We have added support for squares and rectangles too!
- Eunoia uses analytical gradients for all the smooth loss functions, which
  leads to significantly improved performance. We have also swapped the default
  optimization algorithm to a Levendberg--Marquardt (LM) method plus CMA-ES
  fallback. The LM method is invoked only when the loss is squared residuals,
  but is then much faster than the previous `nlm()` method. The CMA-ES fallback
  replaces the previous use of the **GenSA** package, and is invoked whenever
  the LM method reaches a minimum that's above a level of error (configurable by
  the user).
- There are now several labeling algorithms that ensure labels do not overlap
  each other or other parts of the diagram.
- As a result of the above, we have been able to drop multiple dependencies:
  **Rcpp**, **RcppArmadillo**, **GenSA**, **polylabelr**, and **polyclip** are
  all no longer required, since **rextendr** and Eunoia handle the Compiled code
  and algorithms natively.
- The calculated intersections are now *sparse*, which means that only the
  intersections that actually appear in either input or output (the diagram) are
  calculated and stored. This is a **breaking change** because it means that you
  cannot index the intersections by their position or intersection name and
  guarantee that you will get a value. Instead, you must check if the
  intersection exists first, and then implicitly it will have a value of zero.
  But this allows eulerr to handle much larger combinations, since we never
  store a `2^n - 1`-sized vector anywhere.

## Breaking changes

- return sparse residuals ([`decc985`](https://github.com/jolars/eulerr/commit/decc9856f7894296024af3b032f1f056800690ae))

## Features

- add square and rectangle shapes ([`44c9a1a`](https://github.com/jolars/eulerr/commit/44c9a1afb622bf279279a6369c142e4b753b96c3))
- **plotting:** add placement strategies for labels ([`308167a`](https://github.com/jolars/eulerr/commit/308167a599aa0f9a9ac9e7ee6aa780ecbcb6642f))
- add `annotations` argument for annotating intersections ([`19d2d87`](https://github.com/jolars/eulerr/commit/19d2d877cf8b41a5521944531e211e65f82a31b0)), closes [#70](https://github.com/jolars/eulerr/issues/70)
- add plot composing via `+`, `/` and `|` ([`d974c08`](https://github.com/jolars/eulerr/commit/d974c0826d455111dcc7b267477a347898549753)), closes [#46](https://github.com/jolars/eulerr/issues/46)
- expose `gap` and separate labels by gap and tether ([`17802a2`](https://github.com/jolars/eulerr/commit/17802a2459d6ff7bc779205325a47fa2f197a62a))
- add `template` to `quantities` in `plot()` ([`59ddd71`](https://github.com/jolars/eulerr/commit/59ddd71e464978dda91786ca74b3b589a63deb34)), closes [#99](https://github.com/jolars/eulerr/issues/99)
- employ Eunoia's label-placement framework ([`4ed75b4`](https://github.com/jolars/eulerr/commit/4ed75b483c4bf88df50d23451ed2c142c2d24af3)), closes [#69](https://github.com/jolars/eulerr/issues/69) and [#4](https://github.com/jolars/eulerr/issues/4)
- add complement ([`b6ce232`](https://github.com/jolars/eulerr/commit/b6ce23280d4b54b932659f2ce9c73c5df59f5be7)), closes [#13](https://github.com/jolars/eulerr/issues/13)
- add new loss functions, deprectate old and `loss_aggregator` ([`03e7dea`](https://github.com/jolars/eulerr/commit/03e7dea3c813676ee87418a1ef52667f498df4e6))
- add `max_sets` in `control` for capping max sets ([`621a898`](https://github.com/jolars/eulerr/commit/621a898f1e523df8f5d904a3543bb35dd1355ff8)), closes [#85](https://github.com/jolars/eulerr/issues/85)
- add `by_groups` to `plot()` for panel-specifics ([`f2d5533`](https://github.com/jolars/eulerr/commit/f2d5533d594e0b920042a8b0906a39c0994661b0)), closes [#125](https://github.com/jolars/eulerr/issues/125)
- return sparse residuals ([`decc985`](https://github.com/jolars/eulerr/commit/decc9856f7894296024af3b032f1f056800690ae))
- update euonoia to 0.8.0 ([`ceb3138`](https://github.com/jolars/eulerr/commit/ceb313841164760db83a2ac61796fbe9d15125c9))
- update eunoia ([`530fb11`](https://github.com/jolars/eulerr/commit/530fb11ad92b52d8a33d8ed6127bf111df95ffeb))
- lower default tolerance ([`6400fae`](https://github.com/jolars/eulerr/commit/6400fae1f2575542ece0871acf9198a34d00b4ff))
- **plotting:** add `symbol_size` to configure legend symbol ([`1491a49`](https://github.com/jolars/eulerr/commit/1491a494d6fb4d722279fe5d1478dfcb8a792c53)), closes [#60](https://github.com/jolars/eulerr/issues/60)
- **plotting:** add `rotate` parameter ([`706735c`](https://github.com/jolars/eulerr/commit/706735cce7bbfbdf41165f0623a1f5221aaa471e)), closes [#12](https://github.com/jolars/eulerr/issues/12)
- **plots:** support `top` and `left` for labeling strips ([`c1a87fb`](https://github.com/jolars/eulerr/commit/c1a87fb68f41dabda740095bd56adef7b2ec937b)), closes [#123](https://github.com/jolars/eulerr/issues/123)

## Bug fixes

- add padding to avoid clipping plots ([`5129054`](https://github.com/jolars/eulerr/commit/51290543279b843eb03a1b0e8581c43a795fde03))
- use `stats` namespace ([`72df9c8`](https://github.com/jolars/eulerr/commit/72df9c81b03cf13672e46d48cb3406ae0e866e14))

## Performance improvements

- upgrade to eunoia 0.11.0 ([`021ceb4`](https://github.com/jolars/eulerr/commit/021ceb43bd4435b3c108995cc787b69cd9cb8cc5))

# eulerr 7.1

## Features

- allow setting plot options via named vector
  ([`3b7a32e`](https://github.com/jolars/eulerr/commit/3b7a32e945931171f86b1716a47d47807453d9f9)),
  closes [#111](https://github.com/jolars/eulerr/issues/111)
- implement patterns
  ([`caf1c76`](https://github.com/jolars/eulerr/commit/caf1c76dd7c07c24b4f88d114a5d7fac9ab8844d)),
  closes [#83](https://github.com/jolars/eulerr/issues/83)
- set venn diagram class to `venn_eulerr`
  ([`244a657`](https://github.com/jolars/eulerr/commit/244a65758129b75156ada498039baf8b5d47c9db)),
  closes [#78](https://github.com/jolars/eulerr/issues/78)
- add `quantities$format` for number formatting
  ([`b01e69b`](https://github.com/jolars/eulerr/commit/b01e69b8072ea0d45aed27dc74c2a04d09fc2c28)),
  closes [#75](https://github.com/jolars/eulerr/issues/75)
- allow rounding numbers
  ([`6e297a5`](https://github.com/jolars/eulerr/commit/6e297a5b84c63cec0595c38ec1e235be572cda33)),
  closes [#76](https://github.com/jolars/eulerr/issues/76)
- add `bg` option for `plot.euler()`
  ([`bf70290`](https://github.com/jolars/eulerr/commit/bf70290b94e40dc0cf7fd09ba86dbcd29c8adc55)),
  closes [#74](https://github.com/jolars/eulerr/issues/74)
- allow named labels in `quantities`
  ([`4c7d091`](https://github.com/jolars/eulerr/commit/4c7d091d78f286fbdc8a73cacfbeabedaaddeb4a)),
  fixes [#112](https://github.com/jolars/eulerr/issues/112)
- allow expression vectors in `plot.euler()` + `labels`
  ([`cea5e43`](https://github.com/jolars/eulerr/commit/cea5e43313ea1730035d37f0d08b6dc21f8a3623)),
  closes [#118](https://github.com/jolars/eulerr/issues/118)

## Bug fixes

- strictly map colors to set identities
  ([`a58fce5`](https://github.com/jolars/eulerr/commit/a58fce5f44decf449bad6fb3a4d54c041f888d5b)),
  closes [#109](https://github.com/jolars/eulerr/issues/109)
- use correct number of columns in tabular
  ([`4880f5e`](https://github.com/jolars/eulerr/commit/4880f5ebeeebd381665df3affad6841e3dbdd401)),
  closes [#116](https://github.com/jolars/eulerr/issues/116)

# eulerr 7.0.4

## Bug Fixes

- Ignore `air.toml` in `Rbuildignore` to fix R CMD check warning.

# eulerr 7.0.3

## Bug Fixes

- Fix deprecated use of `arma::is_finite()` in C++ code.
- Fix URL link to eulerAPE in documentation.
- Fix URL link to workshop paper in documentation and citation.

# eulerr 7.0.2

## Bug Fixes

- Fix order and layout of strips when grouping (#108, by @altairwei)

# eulerr 7.0.1

## Minor Changes

- Fixed some incorrect documentation of internal functions.
- Corrected an url for eulerAPE.

# eulerr 7.0.0

## New Features

- It is now possible to set the loss function to be used when trying to optimize
  the Euler diagram layout via `loss` and `loss_aggregator`. There is a new
  vignette that showcases this new feature.

## Minor Changes

- C++14 is now required for the package.

## Bug Fixes

- Label repelling via `adjust_labels` in `plot.euler()` has been deprecated and
  removed to fix sanitizer warnings.

# eulerr 6.1.1

## Minor changes

- citation to conference paper added to `inst/CITATION`
- error messages for erroneous input have been improved in several places
- switched `PI` to `M_PI` to support `STRICT_R_HEADERS` in C++ code (#82, thanks
  @eddelbuettel)

## Bug fixes

- error in documentation for list method has been fixed, thanks @gprezza (##77)

# eulerr 6.1.0

## Minor changes

- Label repelling (activated by calling `euler()` with `adjust_labels = TRUE`)
  no longer repels text labels away from the edges of the shapes in the diagram.

## Bug fixes

- Rectify sanitizer error from clang-ASAN test environment.

# eulerr 6.0.2

## Bug fixes

- Set `stringsAsFactors = TRUE` inside all relevant functions in `euler()` to
  avoid errors in upcoming R version.
- Fix broken link in *eulerr under the hood* vignette.

# eulerr 6.0.1

## Minor changes

- Throw an error message when the number of sets in `venn()` exceeds 5 (##65)
- Performance improved when large lists are used as input to `euler()` and
  `venn()` (##64, @privefl)

## Bug fixes

- Correctly handle `data.frame` inputs to `euler()` when categorical variables
  are character vectors and not factors.

# eulerr 6.0.0

## New features

- In `plot.euler()`, percentages can be added to the plot in addition to or
  instead of counts by providing a `list` to the `quantities` argument with an
  item `type` that can take any combination of `counts` and `percent`. This
  change also comes with a redesign of the grid graphics implementation for
  labels.
- `eulerr_options()` gains a new argument `padding` which controls the amount of
  padding between labels and quantities. (##48)
- `plot.euler()` now uses code from the **ggrepel** package to prevent labels
  from overlapping or escaping the plot area if `adjust_labels` is set to
  `TRUE`.
- A new vignette featuring a gallery of plots from the package has been added.

## Minor changes

- The default `cex` for quantity labels has changed from 1.0 to 0.9.
- Labels for sets that overlap are now merged (partly fixes ##45)
- The fill colors for sets which are completely contained within another set are
  now once again composed of a mix of the color of the subset and the superset.
- Plotting data has been exposed in a `data` slot in the object created by
  calling to `plot.euler()` (##57)

## Bug fixes

- An error in layout normalization that occurred sometimes with ellipses has
  been fixed.

## eulerr 5.1.0

## New features

- `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*, exemplifies its
  use.

## Minor changes

- Calculations for the strips in `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.
- Tiny overlaps (where the fraction of the area is less than one thousandth of
  the largest overlap) in the final diagram are no longer plotted.
- `eulergram()` objects from `plot.euler()` now have a proper grob name for the
  canvas grob, so that extracting information from them is easier.

## Bug fixes

- Return value documentation for `euler()` now correctly says "ellipses" and not
  "coefficients".
- `data.frame` or `matrix` inputs now work properly when values are numerical.
  (##42)
- Fixed some spelling errors in news and vignettes.

# eulerr 5.0.0

## New features

- `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.

## Major changes

- `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](https://CRAN.R-project.org/package=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.
- The c++ internals have been rewritten using more memory-efficient, performant
  and expressive code.

## Minor changes

- The `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.
- A few performance fixes.
- Additional unit tests.
- Previously deprecated arguments to `plot.euler()` have been made defunct.
- Added a data set, `plants`, to exemplify the list method for `euler()`.
- Added a data set, `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.
- Added a data set, `organisms`, to exemplify the matrix method for `euler()`.
- Added a data set, `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.
- Parts of the *eulerr under the hood* vignette has been branched off into a new
  vignette regarding visualization.

## Bug fixes

- Empty combinations can now be provided and will be plotted (generating
  completely blank plots).
- `euler.list()` now passes its ellipsis argument along properly. (##33, thanks,
  @banfai)
- Several spelling and grammar mistakes were corrected in vignettes and
  documentation.

# eulerr 4.1.0

## Minor changes

- `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()`.
- Fitting and plotting Euler diagrams with empty sets is now allowed (##23).
  Empty sets in the input will be returned as `NA` in the resulting `data.frame`
  of ellipses.
- The last-ditch optimizer has been switched back to `GenSA::GenSA()` from
  `RcppDE::DEoptim()`.

## Bug fixes

- The **grid** parameters available for *edges* are now correctly specified in
  the manual for `plot.euler()`.
- `euler.data.frame()` now works as expected for tibbles (from the **tibble**
  package) when argument `by` is used.

# eulerr 4.0.0

## Major changes

- `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).
- The default color palette has been redesigned from scratch to suit the new
  plot method.
- A new function `eulerr_options()` have been provided in order to set default
  graphical parameters for the diagrams.

## Minor changes

- Arguments `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.
- Layouts are now partially normalized so that diagrams will look approximately
  the same even with different random seeds.

## Bug fixes

- Providing custom labels to `quantities` and `labels` arguments of
  `plot.euler()` now works correctly (##20).

# eulerr 3.1.0

## Major changes

- The last-ditch optimizer switched from `GenSA::GenSA()` to
  `RcppDE::DEoptim()`.
- The optimizer used in all the remaining cases, including all circular diagrams
  and initial layouts, was switched back to `stats::nlm()` again.
- In final optimization, we now use *stress* instead of residual sums of squares
  as a target for our optimizer.

## Minor changes

- `label` is now a proper generic with an appropriate method (`label.euler()`).
- The **eulerr under the hood** vignette has received a substantial update.

## Bug fixes

- Fixed warnings resulting from the deprecated `counts` argument in one of the
  vignettes.
- Fixed memcheck errors in the final optimizer.
- Corrected erroneous labeling when `auto.key = TRUE` and labels were *not* in
  alphabetic order. (##15)

# eulerr 3.0.1

## Bug fixes

- Added the missing `%\VignetteEngine{knitr::knitr}` to both vignettes. It had
  mistakenly been left out, which had mangled the resulting vignettes.

# eulerr 3.0.0

## Major changes

- Ellipses are now supported by setting the new argument `shape = "ellipse"` in
  `euler()`. This functionality accompanies an overhaul of the innards of the
  function.
- Initial optimization function and gradient have been ported to C++.
- The initial optimizer has been switched from
  `stats::optim(..., method = "L-BFGS-B")` to `stats::nlminb()`.
- The final optimizer now falls back to `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`.
- A packing algorithm has been introduced to arrange disjoint clusters of
  ellipses/circles.
- The label placement algorithm has been rewritten to handle ellipses and been
  ported to C++. It now uses numerical optimization, which should provide
  slightly more accurate locations.
- The initial optimizer now uses an analytical Hessian in addition to gradient.

## Minor changes

- The initial optimizer now restarts up to 10 times and picks the best fit
  (unless it is perfect somewhere along the way).
- The default palette has been changed to a fixed palette, still adapted to
  color deficiency, but with some manual adjustments to, among other things,
  avoid unnecessary use of color.
- The names of the `diagError` and `regionError` metrics have been changed from
  `diag_error` and `region_error` to reflect the original names.
- The coordinates for the centers are now called *h* and *k* instead of *x* and
  *y*, respectively.
- A new `label()` function has been added to extract locations for the overlaps
  for third party plotting (##10).
- The `counts` argument to `plot.euler()` and `panel.euler.labels()` have been
  deprecated in favor of the more appropriate `quantities`.
- Argument `fill_opacity` in `plot.euler()` that was deprecated in
  [v2.0.0](https://github.com/jolars/eulerr/releases/tag/v2.0.0) has been made
  defunct.

# eulerr 2.0.0

## Major changes

- `eulerr()` has been replaced with `euler()` (see update 1.1.0) and made
  defunct.
- There are two new methods for `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.
- Arguments `polygon_args`, `mar`, and `text_args` to `plot.euler()` have been
  made defunct.

## Minor changes

- `plot.euler()` handles conflicting arguments better.
- c++ routines in `eulerr` now use registration.
- `euler()` now allows single sets (##9).
- Labels in `plot.euler()` now use a bold font face by default in order to
  distinguish them from the typeface used for counts.
- Argument `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).
- Argument `fill_opacity` is softly deprecated and has been replaced with
  `fill_alpha` for consistency with other lattice functions.

## Bug fixes

- `border` argument in `plot.euler()` works again (##7).

# eulerr 1.1.0

## Major changes

- `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.

## Minor changes

- Added a `counts` argument to `plot.eulerr`, which intersections and
  complements with counts from the original set specification (##6).
- Added a `key` argument to `plot.eulerr` that prints a legend next to the
  diagram.
- Switched to `atan2()` from RcppArmadillo.
- Added version requirement for RcppArmadillo.
- Dropped dependency on MASS for computing label placement, replacing it with a
  faster, geometric algorithm.
- Dropped the cost function argument `cost` and now forces the function to use
  sums of squares, which is more or less equivalent to the cost function from
  `venneuler`.
- Color palettes in `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.

## Bug fixes

- The previous algorithm incorrectly computed loss from unions of sets. It now
  computes loss from disjoint class combinations.
- Added missing row breaks in `print.eulerr`.

# eulerr 1.0.0

## New features

- Final optimization routines have been completely rewritten in C++ using Rcpp
  and RcppArmadillo.
- Switched to the cost function from EulerAPE for the default optimization
  target but added the possibility to choose cost function via a `cost` argument
  (currently `eulerAPE` or `venneuler`).
- Added the option to produce conditional eulerr plots via a `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.
- Improved label placement by using a two-dimensional kernel density estimation
  instead of means to calculate label centers.

## Bug fixes and minor improvements

- Cleaned up typos and grammar errors in the *Introduction to eulerr* vignette.
- Added `mar` argument to `plot.eulerr` with a default that produces symmetric
  margins.
- Corrected the implementation of the `stress` statistic from venneuler.
- Switched to Vogel sampling to generate points to choose label positions from.
- Minor clean up and performance fixes all around.
- Added a `print.eulerr` method.
- Updated vignette to cover new features and changes.

# eulerr 0.1.0

- The first release.
