thomasp85 / ggforce

Accelerating ggplot2
https://ggforce.data-imaginist.com
Other
916 stars 105 forks source link

Fix missing hulls when concave polygons are not generated for groups #312

Closed yoda-vid closed 7 months ago

yoda-vid commented 10 months ago

I encountered the issues described in #299 and #290, where hulls sometimes miss points.

It appears to happen when polygons aren't generated by concaveman, such groups with 2 or fewer points. concaveman changes the original matrices' column names, but they aren't converted for these groups. Renaming the column names to a consistent set appears to fix this issue.

Here are tests adapted from the two issues listed above:

library(tibble)
library(ggplot2)
library(ggforce)

# set up test from https://github.com/thomasp85/ggforce/issues/299
test_dataset <- tibble(x     = c(-235, -220,  187, -100, -162,   8, 336, 159, 443, -77, -412), 
  y     = c( -32, -147, -123,    6,  102, -14,  40,   6,  15, 115,   30),
  group = c( "a",  "a",  "a",  "b",  "b", "b", "c", "c", "c", "d",  "d"))

# hull misses shapes with 2 points
ggplot(test_dataset, aes(x = x, y = y, fill = group)) + 
  geom_mark_hull() +
  geom_point(shape = 21, size = 3, color = "black")

Before fix: Rplot03

After fix: Rplot02

# set up test from https://github.com/thomasp85/ggforce/issues/290
x <- c(-4.46798966620377, -2.1090312453605, -1.84601768294516, 5.79499827429486, 0.43592398267521, -3.01641689187153, -4.10398493436269, -1.53467832497444, -1.64403248330696, 1.88866969350521, -1.10071376022678, -0.732424476000914, 4.9355457310868, 7.16901087881661, -11.1749760466164, -0.330647142722807, 4.99431746262638, 3.99350248184654, 5.57024373532071, -4.9003441612954, -2.70964164932524, -3.13827001445066, 8.98938301829994, 1.15304888846147, -4.10835606970075, -3.80814439783665, -1.11500667144161, -4.01741501531724, 0.600033270173348, -1.80874358837064, -0.381658708050097, 6.46574124184736, 6.37340082097916, 0.273747698054138, 4.90249513991362, 6.16139025975088, 2.62462429559324, 5.36868924362433, -6.21295925665591, -2.27676433338093, -1.23143424193455, 5.79794917170878, 1.39159889636088, -3.27991565841227, -3.32113773742275, -1.89630876814511, -3.93776678590554, 0.785189427950814, -0.794902846480633, -0.628082507785516, 5.74575717936985, 7.04070961795171, 0.788392068682478, 5.60989643609462, 4.22291712058141, 2.10055019294984, 5.85725439334508)
y <- c(-1.88979052125517, -3.99859032133039, 2.88794711532744, 1.04400982509528, -9.20071736934793, -0.874436876290539, -5.01035759345655, 1.56129515932716, -2.28617788003896, 1.46927851645699, -1.23088074711093, -0.0512634990258398, 0.855694107232475, 5.24359789459775, -5.19349234505035, -5.80406825757198, 2.0373710339048, 3.66304250612958, 2.47355081727165, -2.91698101544892, -3.68956634231607, 5.84439063122804, 0.596732520647421, -8.31179169039804, -0.63493227634592, -5.93821117884396, 1.019956220117, -3.25066580239872, 1.34229087097502, -1.24120130291848, 1.55903028956034, 2.09890123632997, 4.16912629275164, -7.18715263054722, 3.06941990106059, 3.14300986520884, 3.17857513049073, 4.73226062353877, -3.44527637667008, -3.41082697427231, 3.63529860825317, 1.63130316772536, -9.30339326171906, -0.196903044477533, -5.23904552721807, 0.814520292592067, -2.58187687963695, 0.83932864039429, -1.73754258868063, 0.524089051459452, 0.100885472398243, 4.28702335064132, -5.19405687460876, 3.27950050157283, 2.34740358671191, 3.9834926184684, 5.45626038770104)
celltype <- c("Amnion", "Endoderm", "Endothelial & erythroid cell", "Ependymal cell", "Epiblast", "Epithelium", "ExE endoderm", "ExE mesoderm", "Gut", "Limb bud mesenchyme cell", "Mesoderm", "MSC/Fib", "Neural ectoderm", "Neuron", "PGC", "Primitive streak", "Radial glial cell", "Retinal pigmented epithelium", "Retinal progenitor cell", "Amnion & PGC", "Endoderm", "Endothelial & erythroid cell", "Ependymal cell", "Epiblast", "Epithelium", "ExE endoderm", "ExE mesoderm", "Gut", "Limb bud mesenchyme cell", "Mesoderm", "MSC/Fib", "Neural ectoderm", "Neuron", "Primitive streak", "Radial glial cell", "Retinal progenitor cell", "Schwann cell", "Sensory neuron", "Amnion & PGC", "Endoderm", "Endothelial & erythroid cell", "Ependymal cell", "Epiblast", "Epithelium", "ExE endoderm", "ExE mesoderm", "Gut", "Limb bud mesenchyme cell", "Mesoderm", "MSC/Fib", "Neural ectoderm", "Neuron", "Primitive streak", "Radial glial cell", "Retinal progenitor cell & RPE", "Schwann cell", "Sensory neuron")
df <- data.frame(x = x, y = y, celltype = celltype)

# hull misses many groups
ggplot(data = df, aes(x, y)) +
  geom_point(mapping = aes(color = celltype)) +
  geom_mark_hull(mapping = aes(fill = celltype))

Before fix: Rplot04

After fix: Rplot01

Hope this helps.

road2you commented 8 months ago

I have devised the following temporary method to bypass errors by using the filter option.

example 1

set up test from https://github.com/thomasp85/ggforce/issues/299

test_dataset <- tibble(x = c(-235, -220, 187, -100, -162, 8, 336, 159, 443, -77, -412), y = c( -32, -147, -123, 6, 102, -14, 40, 6, 15, 115, 30), group = c( "a", "a", "a", "b", "b", "b", "c", "c", "c", "d", "d"))

ggplot(test_dataset, aes(x = x, y = y, fill = group)) + geom_mark_hull() +

add hull layer only to the group that have just two points

geom_mark_hull(aes(x = x, y = y, fill = group, filter = group=="d")) + geom_point(shape = 21, size = 3, color = "black")

Screenshot from 2023-12-18 16-04-11

example 2

set up test from https://github.com/thomasp85/ggforce/issues/290

x <- c(-4.46798966620377, -2.1090312453605, -1.84601768294516, 5.79499827429486, 0.43592398267521, -3.01641689187153, -4.10398493436269, -1.53467832497444, -1.64403248330696, 1.88866969350521, -1.10071376022678, -0.732424476000914, 4.9355457310868, 7.16901087881661, -11.1749760466164, -0.330647142722807, 4.99431746262638, 3.99350248184654, 5.57024373532071, -4.9003441612954, -2.70964164932524, -3.13827001445066, 8.98938301829994, 1.15304888846147, -4.10835606970075, -3.80814439783665, -1.11500667144161, -4.01741501531724, 0.600033270173348, -1.80874358837064, -0.381658708050097, 6.46574124184736, 6.37340082097916, 0.273747698054138, 4.90249513991362, 6.16139025975088, 2.62462429559324, 5.36868924362433, -6.21295925665591, -2.27676433338093, -1.23143424193455, 5.79794917170878, 1.39159889636088, -3.27991565841227, -3.32113773742275, -1.89630876814511, -3.93776678590554, 0.785189427950814, -0.794902846480633, -0.628082507785516, 5.74575717936985, 7.04070961795171, 0.788392068682478, 5.60989643609462, 4.22291712058141, 2.10055019294984, 5.85725439334508) y <- c(-1.88979052125517, -3.99859032133039, 2.88794711532744, 1.04400982509528, -9.20071736934793, -0.874436876290539, -5.01035759345655, 1.56129515932716, -2.28617788003896, 1.46927851645699, -1.23088074711093, -0.0512634990258398, 0.855694107232475, 5.24359789459775, -5.19349234505035, -5.80406825757198, 2.0373710339048, 3.66304250612958, 2.47355081727165, -2.91698101544892, -3.68956634231607, 5.84439063122804, 0.596732520647421, -8.31179169039804, -0.63493227634592, -5.93821117884396, 1.019956220117, -3.25066580239872, 1.34229087097502, -1.24120130291848, 1.55903028956034, 2.09890123632997, 4.16912629275164, -7.18715263054722, 3.06941990106059, 3.14300986520884, 3.17857513049073, 4.73226062353877, -3.44527637667008, -3.41082697427231, 3.63529860825317, 1.63130316772536, -9.30339326171906, -0.196903044477533, -5.23904552721807, 0.814520292592067, -2.58187687963695, 0.83932864039429, -1.73754258868063, 0.524089051459452, 0.100885472398243, 4.28702335064132, -5.19405687460876, 3.27950050157283, 2.34740358671191, 3.9834926184684, 5.45626038770104) celltype <- c("Amnion", "Endoderm", "Endothelial & erythroid cell", "Ependymal cell", "Epiblast", "Epithelium", "ExE endoderm", "ExE mesoderm", "Gut", "Limb bud mesenchyme cell", "Mesoderm", "MSC/Fib", "Neural ectoderm", "Neuron", "PGC", "Primitive streak", "Radial glial cell", "Retinal pigmented epithelium", "Retinal progenitor cell", "Amnion & PGC", "Endoderm", "Endothelial & erythroid cell", "Ependymal cell", "Epiblast", "Epithelium", "ExE endoderm", "ExE mesoderm", "Gut", "Limb bud mesenchyme cell", "Mesoderm", "MSC/Fib", "Neural ectoderm", "Neuron", "Primitive streak", "Radial glial cell", "Retinal progenitor cell", "Schwann cell", "Sensory neuron", "Amnion & PGC", "Endoderm", "Endothelial & erythroid cell", "Ependymal cell", "Epiblast", "Epithelium", "ExE endoderm", "ExE mesoderm", "Gut", "Limb bud mesenchyme cell", "Mesoderm", "MSC/Fib", "Neural ectoderm", "Neuron", "Primitive streak", "Radial glial cell", "Retinal progenitor cell & RPE", "Schwann cell", "Sensory neuron") df <- data.frame(x = x, y = y, celltype = celltype)

count the number of points in each group

df <- df %>% group_by(celltype) %>% mutate(freq = n())

ggplot(data = df, aes(x, y)) + geom_point(mapping = aes(color = celltype)) + geom_mark_hull(mapping = aes(fill = celltype)) +

add hull layer only to the group that have more than two points

geom_mark_hull(mapping = aes(fill = celltype, filter = freq >2))

Screenshot from 2023-12-18 16-03-57

thomasp85 commented 7 months ago

Thank you so much