Skip to content

Commit

Permalink
Redesign functionality for plotting percentages and add label-adjustm…
Browse files Browse the repository at this point in the history
…ent, which fixes #45
  • Loading branch information
Johan Larsson committed Jul 13, 2019
1 parent d101e2d commit e8bba17
Show file tree
Hide file tree
Showing 20 changed files with 1,558 additions and 238 deletions.
5 changes: 4 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ Authors@R: c(person("Johan", "Larsson", email = "mail@larssonjohan.com",
person("David H.", "Eberly", role = "ctb",
comment = "geometric algorithms"),
person("Emanuel", "Huber", role = "ctb",
comment = "root solver code"))
comment = "root solver code"),
person("Kamil", "Slowikowski", role = c("ctb", "cph"),
comment = c(ORCID = "0000-0002-2843-6370",
"modified code from ggrepel")))
Description: 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
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ S3method(euler,list)
S3method(euler,matrix)
S3method(euler,table)
S3method(fitted,euler)
S3method(makeContent,EulerTags)
S3method(plot,euler)
S3method(plot,eulergram)
S3method(plot,venn)
Expand Down
18 changes: 11 additions & 7 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

## New features

* `plot.euler()` gains a `percentages` argument, which adds the
mass/count of each overlap as a percentage of the total. This change
also comes with a fundamental redesign of the approach to adding labels, now
setting up each label, quantity, and percentage as a unified grob (in grid
graphics terminology). Moreover, `eulerr_options()` now has a new argument
`padding` which controls the amount of padding between labels, quantities,
and percentages. (#48)
* 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`.

## Minor changes

Expand Down
127 changes: 127 additions & 0 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,133 @@
# Generated by using Rcpp::compileAttributes() -> do not edit by hand
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393

#' Euclidean distance between two points.
#' @param a A numeric vector.
#' @param b A numeric vector.
#' @return The distance between two points.
#' @noRd
NULL

#' Get the coordinates of the center of a box.
#' @param b A box like \code{c(x1, y1, x2, y2)}
#' @noRd
NULL

#' Find the intersections between a line and a rectangle.
#' @param c A circle like \code{c(x, y, r)}
#' @param r A rectangle like \code{c(x1, y1, x2, y2)}
#' @noRd
NULL

#' Find the intersections between a line and a rectangle.
#' @param p1 A point like \code{c(x, y)}
#' @param p2 A point like \code{c(x, y)}
#' @param b A rectangle like \code{c(x1, y1, x2, y2)}
#' @noRd
NULL

#' Euclidean distance between two points.
#' @param a A point.
#' @param b A point.
#' @return The distance between two points.
#' @noRd
NULL

#' Squared Euclidean distance between two points.
#' @param a A point.
#' @param b A point.
#' @return The distance between two points.
#' @noRd
NULL

#' Move a box into the area specificied by x limits and y limits.
#' @param b A box like \code{c(x1, y1, x2, y2)}
#' @param xlim A Point with limits on the x axis like \code{c(xmin, xmax)}
#' @param ylim A Point with limits on the y axis like \code{c(xmin, xmax)}
#' @param force Magnitude of the force (defaults to \code{1e-6})
#' @noRd
NULL

#' Get the coordinates of the center of a box.
#' @param b A box like \code{c(x1, y1, x2, y2)}
#' @noRd
NULL

#' Test if a box overlaps another box.
#' @param a A box like \code{c(x1, y1, x2, y2)}
#' @param b A box like \code{c(x1, y1, x2, y2)}
#' @noRd
NULL

#' Test if a box overlaps another box.
#' @param a A box like \code{c(x1, y1, x2, y2)}
#' @param b A box like \code{c(x1, y1, x2, y2)}
#' @noRd
NULL

#' Compute the repulsion force upon point \code{a} from point \code{b}.
#'
#' The force decays with the squared distance between the points, similar
#' to the force of repulsion between magnets.
#'
#' @param a A point like \code{c(x, y)}
#' @param b A point like \code{c(x, y)}
#' @param force Magnitude of the force (defaults to \code{1e-6})
#' @param direction direction in which to exert force, either "both", "x", or "y"
#' @noRd
NULL

#' Compute the spring force upon point \code{a} from point \code{b}.
#'
#' The force increases with the distance between the points, similar
#' to Hooke's law for springs.
#'
#' @param a A point like \code{c(x, y)}
#' @param b A point like \code{c(x, y)}
#' @param force Magnitude of the force (defaults to \code{1e-6})
#' @param direction direction in which to exert force, either "both", "x", or "y"
#' @noRd
NULL

#' Adjust the layout of a list of potentially overlapping boxes.
#' @param data_points A numeric matrix with rows representing points like
#' \code{rbind(c(x, y), c(x, y), ...)}
#' @param point_padding_x Padding around each data point on the x axis.
#' @param point_padding_y Padding around each data point on the y axis.
#' @param boxes A numeric matrix with rows representing boxes like
#' \code{rbind(c(x1, y1, x2, y2), c(x1, y1, x2, y2), ...)}
#' @param xlim A numeric vector representing the limits on the x axis like
#' \code{c(xmin, xmax)}
#' @param ylim A numeric vector representing the limits on the y axis like
#' \code{c(ymin, ymax)}
#' @param force Magnitude of the force (defaults to \code{1e-6})
#' @param maxiter Maximum number of iterations to try to resolve overlaps
#' (defaults to 2000)
#' @noRd
repel_boxes <- function(data_points, point_padding_x, point_padding_y, boxes, xlim, ylim, hjust, vjust, force_push = 1e-7, force_pull = 1e-7, maxiter = 2000L, direction = "both") {
.Call(`_eulerr_repel_boxes`, data_points, point_padding_x, point_padding_y, boxes, xlim, ylim, hjust, vjust, force_push, force_pull, maxiter, direction)
}

#' Adjust the layout of a list of potentially overlapping boxes.
#' @param data_points A numeric matrix with rows representing points like
#' \code{rbind(c(x, y), c(x, y), ...)}
#' @param point_size A numeric vector representing the sizes of data points.
#' @param point_padding_x Padding around each data point on the x axis.
#' @param point_padding_y Padding around each data point on the y axis.
#' @param boxes A numeric matrix with rows representing boxes like
#' \code{rbind(c(x1, y1, x2, y2), c(x1, y1, x2, y2), ...)}
#' @param xlim A numeric vector representing the limits on the x axis like
#' \code{c(xmin, xmax)}
#' @param ylim A numeric vector representing the limits on the y axis like
#' \code{c(ymin, ymax)}
#' @param force Magnitude of the force (defaults to \code{1e-6})
#' @param maxiter Maximum number of iterations to try to resolve overlaps
#' (defaults to 2000)
#' @noRd
repel_boxes2 <- function(data_points, point_size, point_padding_x, point_padding_y, boxes, xlim, ylim, hjust, vjust, force_push = 1e-7, force_pull = 1e-7, maxiter = 2000L, direction = "both") {
.Call(`_eulerr_repel_boxes2`, data_points, point_size, point_padding_x, point_padding_y, boxes, xlim, ylim, hjust, vjust, force_push, force_pull, maxiter, direction)
}

intersect_ellipses <- function(par, circle, approx = FALSE) {
.Call(`_eulerr_intersect_ellipses`, par, circle, approx)
}
Expand Down
19 changes: 3 additions & 16 deletions R/eulerr_options.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
#' \item{labels}{a list of items `rot`,
#' `col`, `alpha`, `fontsize`, `cex`, `fontfamily`, `fontface`,
#' `lineheight`, and `font`}
#' \item{quantities}{a list of items `rot`,
#' `col`, `alpha`, `fontsize`, `cex`, `fontfamily`,
#' `lineheight`, and `font`}
#' \item{percentages}{a list with items `rot`,
#' \item{quantities}{a list of items `type`, `rot`,
#' `col`, `alpha`, `fontsize`, `cex`, `fontfamily`,
#' `lineheight`, and `font`}
#' \item{strips}{`col`, `alpha`, `fontsize`, `cex`, `fontfamily`,
Expand Down Expand Up @@ -65,7 +62,6 @@ eulerr_options <- function(...) {
.eulerr_env$options,
list(labels = list(fontsize = pointsize),
quantities = list(fontsize = pointsize),
percentages = list(fontsize = pointsize),
strips = list(fontsize = pointsize),
legend = list(fontsize = pointsize),
main = list(fontsize = pointsize),
Expand Down Expand Up @@ -116,6 +112,7 @@ eulerr_default_options <- function() {
font = 2
),
quantities = list(
type = "numbers",
rot = 0,
col = 1L,
alpha = 1,
Expand All @@ -125,16 +122,6 @@ eulerr_default_options <- function() {
lineheight = 1.2,
font = 1
),
percentages = list(
rot = 0,
col = 1,
alpha = 1,
fontsize = 12,
cex = 1,
fontfamily = "",
lineheight = 1.2,
font = 1
),
strips = list(
cex = 1L,
col = 1L,
Expand Down Expand Up @@ -178,7 +165,7 @@ eulerr_default_options <- function() {
lineheight = 1.2,
alpha = 1
),
padding = grid::unit(0.2, "lines")
padding = grid::unit(0.4, "lines")
)
}

Loading

0 comments on commit e8bba17

Please sign in to comment.