setup_data
functionsetup_data
data functioncompute_group
functioncompute_group
row processing functionsetup_data
and compute_group
functions will be inputsgeom_circle
, inheriting from GeomPolygon
geom_circle
geom_circle
from ggforce; hope renewedlayer_data
to look at the data frameStep 0: Do it with ggplot2.
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.0 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.1 ✔ tibble 3.1.8
## ✔ lubridate 1.9.2 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
create_circle <- function(x0, y0, r = 1, n = 7){
angles <- seq(from = 0,
to = 2 * pi,
length.out = n)
data.frame(
x = c(x0 + r * cos(angles)),
y = c(y0 + r * sin(angles))
)
}
cars %>%
.[1:5,] ->
five_cars
five_cars %>%
mutate(diamond =
purrr::map2(.x = speed,
.y = dist,
create_circle)) %>%
mutate(group = row_number()) %>%
unnest() ->
five_cars_circles
## Warning: `cols` is now required when using `unnest()`.
## ℹ Please use `cols = c(diamond)`.
five_cars %>%
ggplot() +
aes(x = speed, dist) +
geom_point() +
geom_polygon(data = five_cars_circles,
aes(x = x, y = y, group = group),
alpha = .5) +
coord_equal()
setup_data
functionsetup_data_circle <- function(data, params) {
if (data$group[1] == -1) {
nrows <- nrow(data)
data$group <- seq_len(nrows)
}
data # return data with a group variable
}
setup_data
data functioncars %>%
slice(1:5) %>%
mutate(group = -1) %>% # no grouping neg one is default in ggplot2
setup_data_circle() # setup makes each row defines a group
## speed dist group
## 1 4 2 1
## 2 4 10 2
## 3 7 4 3
## 4 7 22 4
## 5 8 16 5
cars %>%
slice(5:20) %>%
mutate(group = 2) %>% # if a group is already defined
setup_data_circle() # setup data does not do anything
## speed dist group
## 1 8 16 2
## 2 9 10 2
## 3 10 18 2
## 4 10 26 2
## 5 10 34 2
## 6 11 17 2
## 7 11 28 2
## 8 12 14 2
## 9 12 20 2
## 10 12 24 2
## 11 12 28 2
## 12 13 26 2
## 13 13 34 2
## 14 13 34 2
## 15 13 46 2
## 16 14 26 2
compute_group
functionWe write a routine that will act on each group in the data (in this case each row)
compute_group_circle <- function(data, scales, n = 5){
angles <- seq(from = 0,
to = 2 * pi,
length.out = n)
data.frame(
x = c(data$x0 + data$r * cos(angles)),
y = c(data$y0 + data$r * sin(angles)),
data
)
}
compute_group
row processing functioncars %>%
rename(x0 = dist, y0 = speed) %>%
mutate(r = x0) %>%
.[1,] %>%
compute_group_circle(n = 6)
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
## x y y0 x0 r
## 1 4.000000 4.000000 4 2 2
## 2 2.618034 5.902113 4 2 2
## 3 0.381966 5.175571 4 2 2
## 4 0.381966 2.824429 4 2 2
## 5 2.618034 2.097887 4 2 2
## 6 4.000000 4.000000 4 2 2
cars %>%
rename(x0 = dist, y0 = speed) %>%
mutate(r = x0) %>%
.[5,] %>%
compute_group_circle(n = 6) %>%
ggplot() +
aes(x = x, y = y) +
geom_polygon(alpha = .5) +
coord_equal()
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
setup_data
and compute_group
functions will be inputsStatCircle <- ggproto(`_class` = "StatCircle",
`_inherit` = Stat,
setup_data = setup_data_circle,
compute_group = compute_group_circle,
required_aes = c("x0", "y0", "r")
)
geom_circle
, inheriting from GeomPolygon
geom_circle <- function(mapping = NULL,
data = NULL,
stat = "circle",
position = "identity",
...,
n = 8,
lineend = "butt",
linejoin = "round",
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomPolygon,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
n = n,
lineend = lineend,
linejoin = linejoin,
na.rm = na.rm,
...
)
)
}
geom_circle
test_df <- data.frame(
x0 = c(-5, 5),
y0 = c(5, -5),
r = c(5, 4),
class = c("a", "b")
)
cars %>%
slice(1:5) %>%
ggplot() +
aes(x = speed, y = dist) +
geom_point() +
aes(x0 = speed,
y0 = dist,
r = speed/6) +
coord_equal() ->
baseplot
baseplot +
geom_circle(n = 7, alpha = .2)
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
baseplot +
aes(fill = speed == 6) +
geom_circle(n = 7, alpha = .2)
## Warning in data$r * cos(angles): longer object length is not a multiple of
## shorter object length
## Warning in data$x0 + data$r * cos(angles): longer object length is not a
## multiple of shorter object length
## Warning in data$r * sin(angles): longer object length is not a multiple of
## shorter object length
## Warning in data$y0 + data$r * sin(angles): longer object length is not a
## multiple of shorter object length
## Warning: Computation failed in `stat_circle()`
## Caused by error in `data.frame()`:
## ! arguments imply differing number of rows: 7, 5
baseplot +
aes(fill = speed > 6) +
geom_circle(n = 7, alpha = .2)
## Warning in data$r * cos(angles): longer object length is not a multiple of
## shorter object length
## Warning in data$x0 + data$r * cos(angles): longer object length is not a
## multiple of shorter object length
## Warning in data$r * sin(angles): longer object length is not a multiple of
## shorter object length
## Warning in data$y0 + data$r * sin(angles): longer object length is not a
## multiple of shorter object length
## Warning: Computation failed in `stat_circle()`
## Caused by error in `data.frame()`:
## ! arguments imply differing number of rows: 7, 2
geom_circle
from ggforce; hope renewedbaseplot +
aes(fill = speed > 6) +
ggforce::geom_circle(n = 5)
## Warning: Using the `size` aesthetic in this geom was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` in the `default_aes` field and elsewhere instead.
layer_data
to look at the data framebaseplot +
geom_circle(n = 7, alpha = .2) ->
p1
layer_data(p1, 2)
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
## Warning in data.frame(x = c(data$x0 + data$r * cos(angles)), y = c(data$y0 + :
## row names were found from a short variable and have been discarded
## x y x0 y0 r x.1 y.1 PANEL group colour fill
## 1 4.666667 2.000000 4 2 0.6666667 4 2 1 1 NA grey20
## 2 4.333333 2.577350 4 2 0.6666667 4 2 1 1 NA grey20
## 3 3.666667 2.577350 4 2 0.6666667 4 2 1 1 NA grey20
## 4 3.333333 2.000000 4 2 0.6666667 4 2 1 1 NA grey20
## 5 3.666667 1.422650 4 2 0.6666667 4 2 1 1 NA grey20
## 6 4.333333 1.422650 4 2 0.6666667 4 2 1 1 NA grey20
## 7 4.666667 2.000000 4 2 0.6666667 4 2 1 1 NA grey20
## 8 4.666667 10.000000 4 10 0.6666667 4 10 1 2 NA grey20
## 9 4.333333 10.577350 4 10 0.6666667 4 10 1 2 NA grey20
## 10 3.666667 10.577350 4 10 0.6666667 4 10 1 2 NA grey20
## 11 3.333333 10.000000 4 10 0.6666667 4 10 1 2 NA grey20
## 12 3.666667 9.422650 4 10 0.6666667 4 10 1 2 NA grey20
## 13 4.333333 9.422650 4 10 0.6666667 4 10 1 2 NA grey20
## 14 4.666667 10.000000 4 10 0.6666667 4 10 1 2 NA grey20
## 15 8.166667 4.000000 7 4 1.1666667 7 4 1 3 NA grey20
## 16 7.583333 5.010363 7 4 1.1666667 7 4 1 3 NA grey20
## 17 6.416667 5.010363 7 4 1.1666667 7 4 1 3 NA grey20
## 18 5.833333 4.000000 7 4 1.1666667 7 4 1 3 NA grey20
## 19 6.416667 2.989637 7 4 1.1666667 7 4 1 3 NA grey20
## 20 7.583333 2.989637 7 4 1.1666667 7 4 1 3 NA grey20
## 21 8.166667 4.000000 7 4 1.1666667 7 4 1 3 NA grey20
## 22 8.166667 22.000000 7 22 1.1666667 7 22 1 4 NA grey20
## 23 7.583333 23.010363 7 22 1.1666667 7 22 1 4 NA grey20
## 24 6.416667 23.010363 7 22 1.1666667 7 22 1 4 NA grey20
## 25 5.833333 22.000000 7 22 1.1666667 7 22 1 4 NA grey20
## 26 6.416667 20.989637 7 22 1.1666667 7 22 1 4 NA grey20
## 27 7.583333 20.989637 7 22 1.1666667 7 22 1 4 NA grey20
## 28 8.166667 22.000000 7 22 1.1666667 7 22 1 4 NA grey20
## 29 9.333333 16.000000 8 16 1.3333333 8 16 1 5 NA grey20
## 30 8.666667 17.154701 8 16 1.3333333 8 16 1 5 NA grey20
## 31 7.333333 17.154701 8 16 1.3333333 8 16 1 5 NA grey20
## 32 6.666667 16.000000 8 16 1.3333333 8 16 1 5 NA grey20
## 33 7.333333 14.845299 8 16 1.3333333 8 16 1 5 NA grey20
## 34 8.666667 14.845299 8 16 1.3333333 8 16 1 5 NA grey20
## 35 9.333333 16.000000 8 16 1.3333333 8 16 1 5 NA grey20
## linewidth linetype alpha
## 1 0.5 1 0.2
## 2 0.5 1 0.2
## 3 0.5 1 0.2
## 4 0.5 1 0.2
## 5 0.5 1 0.2
## 6 0.5 1 0.2
## 7 0.5 1 0.2
## 8 0.5 1 0.2
## 9 0.5 1 0.2
## 10 0.5 1 0.2
## 11 0.5 1 0.2
## 12 0.5 1 0.2
## 13 0.5 1 0.2
## 14 0.5 1 0.2
## 15 0.5 1 0.2
## 16 0.5 1 0.2
## 17 0.5 1 0.2
## 18 0.5 1 0.2
## 19 0.5 1 0.2
## 20 0.5 1 0.2
## 21 0.5 1 0.2
## 22 0.5 1 0.2
## 23 0.5 1 0.2
## 24 0.5 1 0.2
## 25 0.5 1 0.2
## 26 0.5 1 0.2
## 27 0.5 1 0.2
## 28 0.5 1 0.2
## 29 0.5 1 0.2
## 30 0.5 1 0.2
## 31 0.5 1 0.2
## 32 0.5 1 0.2
## 33 0.5 1 0.2
## 34 0.5 1 0.2
## 35 0.5 1 0.2
baseplot +
aes(fill = speed > 6) +
geom_circle(n = 7, alpha = .2) ->
p2
layer_data(p2, 2)
## Warning in data$r * cos(angles): longer object length is not a multiple of
## shorter object length
## Warning in data$x0 + data$r * cos(angles): longer object length is not a
## multiple of shorter object length
## Warning in data$r * sin(angles): longer object length is not a multiple of
## shorter object length
## Warning in data$y0 + data$r * sin(angles): longer object length is not a
## multiple of shorter object length
## Warning: Computation failed in `stat_circle()`
## Caused by error in `data.frame()`:
## ! arguments imply differing number of rows: 7, 2
## data frame with 0 columns and 0 rows