Skip to contents

This function distributes points in a ellipse via a sunflower seed algorithm as a solution for over-plotting. To implement the algorithm, this function adapts the code from https://stackoverflow.com/questions/28567166/uniformly-distribute-x-points-inside-a-circle.

Usage

sunflower(x = NULL, y = NULL, density, aspect_ratio)

Arguments

x, y

The identical coordinates of multiple over-plotted points, as vectors, which will be arranged using a sunflower seed algorithm.

density

The pattern density.

aspect_ratio

An aspect ratio adjustment to compensate for distortion of the circular arrangement, which might occur when plotting if coord_equal() is not used. A wide aspect ratio (eg. 2) would adjust for vertical stretching, whereas a tall aspect ratio (eg. 0.5) would adjust for horizontal stretching. An aspect ratio of 1 is appropriate when no adjustment is required.

Value

A numeric vector of adjusted x or y positions, computed using a sunflower seed algorithm.

Examples

  library(ggplot2)
  library(dplyr)

  # Manually adjust position of N points,
  # arranging them per the sunflower algorithm and then dodging groups
  N <- 300

  dat <- data.frame(
    x = sample(1:2, size = N, replace = TRUE),
    y = sample(1:7, size = N, replace = TRUE),
    type = factor(sample(LETTERS[1:2], N, replace = TRUE))
  ) |>
    group_by(x, y, type) |>
    mutate(
      x = sunflower(x = x, density = 1, aspect_ratio = 1),
      y = sunflower(y = y, density = 1, aspect_ratio = 1),
      x = if_else(type == "A", x - (1 / 8), x + (1 / 8))
    )

  ggplot(dat, aes(x, y, color = type, shape = type)) +
    geom_point() + coord_equal()