ggforce icon indicating copy to clipboard operation
ggforce copied to clipboard

feature: geom_mark_shape

Open assaron opened this issue 6 months ago • 2 comments

Hi,

This is an initial take on geom_mark_shape which provides an option to manually specify polygon for the mark (issue #333).

There are two key changes:

  1. Setting concavity=NA in hull geometry makes it skip the hull construction step and lead to using the points as is.
  2. geom_mark_shape function returns the hull geometry with concavity=NA and has different defaults from geom_mark_hull: radius=0 and expand=0.

Example of the usage:

poly <- data.frame(
    x = c(0, 3, 3, 2, 2, 1, 1, 0),
    y = c(0, 0, 3, 3, 1, 1, 3, 3)
)

set.seed(42)
points <- data.frame(
    x=runif(100, min=0, max=3),
    y=runif(100, min=0, max=3))

points <- points[abs(points$x - 1.5) > 0.5 | points$y < 1, ]

ggplot(points, aes(x=x, y=y)) +
    geom_point() +
    geom_mark_shape(data=poly, color="red")

image

assaron avatar Jun 26 '25 14:06 assaron

I realized that I forgot to include actual labels into the example :) Here is a better one:

library(ggplot2)
library(ggforce)
shape1 <- data.frame(
    x = c(0, 3, 3, 2, 2, 1, 1, 0),
    y = c(0, 0, 3, 3, 1, 1, 3, 3),
    label="bracket"
)
shape2 <- data.frame(
    x = c(0, 3, 3, 0)+4,
    y = c(0, 0, 3, 3),
    label="square"
)
shape3 <- data.frame(
    x = c(0, 1.5, 3, 1.5)+8,
    y = c(1.5, 0, 1.5, 3),
    label="diamond"
)

ggplot(rbind(shape1, shape2, shape3), aes(x=x, y=y, label=label, color=label, fill=label)) +
    geom_mark_shape() +
    ylim(0, 5)

image

assaron avatar Jun 26 '25 15:06 assaron

@thomasp85 can you please check this PR? It should be relatively straightforward.

assaron avatar Nov 14 '25 23:11 assaron