library(ggplot2)
library(tidyverse)
diamonds %>%
count(cut) %>%
ggplot() +
aes(amount = n, r0 = 0, r = 1, fill = cut, x0 = 0, y0 = 0) +
ggforce::stat_pie()
## 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.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Here we’re mostly piggybacking on ggforce::StatPie, but we’d like to have more default rather than required aesthetics, an the external circle area to be meaningful; so data$amount
compute_panel_wedge <- function(data, scales, n = 360, sep = 0){
# defaulting aesthetics, instead of requiring
if(!("x0" %in% names(data))){data$x0 <- 0}
if(!("y0" %in% names(data))){data$y0 <- 0}
if(!("r0" %in% names(data))){data$r0 <- 0}
if(!("r" %in% names(data))) {data$r <- sqrt(sum(data$amount)/pi)} # area will be equal to amount
# maybe change 'amount' to 'weight'?
# piggybacking from StatPie
ggforce::StatPie$compute_panel(data, scales = scales, n = n, sep = sep)
}
We define a StatWedge, which is closely related to ggforce::StatPie, but has fewer required aesthetics.
# For reference... showing the abreviated ggforce::StatPie
# StatPie <- ggproto('StatPie', Stat,
# compute_panel = function(data, scales, n = 360, sep = 0) {.......},
# required_aes = c('x0', 'y0', 'r0', 'r', 'amount'),
# default_aes = aes(explode = NULL)
# )
StatWedge <- ggplot2::ggproto(
`_class` = 'StatWedge',
`_inherit` = ggplot2::Stat,
compute_panel = compute_panel_wedge,
required_aes = c('amount'),
default_aes = ggplot2::aes(x0 = NULL, y0 = NULL,
r0 = NULL, r = NULL,
explode = NULL)
)
# Gentle modification from ggforce::GeomArcBar, changing color (was black) and fill (was NA) defaults
GeomArcWedge <- ggplot2::ggproto('GeomArcWedge', ggforce::GeomShape,
default_aes = ggforce:::combine_aes(ggforce::GeomShape$default_aes,
ggplot2::aes(colour = NA, fill = "grey"))
)
Almost same as stat_pie, but using the GeomArcWedge defined above and StatWedge defined above
geom_wedge <- function(mapping = NULL, data = NULL, geom = 'arc_wedge', stat = StatWedge,
position = 'identity', n = 360, sep = 0, na.rm = FALSE,
show.legend = NA, inherit.aes = TRUE, ...) {
layer(
stat = stat, data = data, mapping = mapping, geom = geom,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, n = n, sep = sep, ...)
)
}
diamonds %>%
count(cut) %>%
ggplot() +
aes(amount = n, fill = cut) +
geom_wedge()
library(tidyverse)
diamonds %>%
count(cut) %>%
ggplot() +
aes(amount = n) +
geom_wedge()
last_plot() +
aes(fill = cut)
last_plot() +
aes(alpha = n)
last_plot() +
aes(r0 = .5, r = 1)
last_plot() +
aes(x0 = 5)
last_plot() +
aes(r = n)
diamonds |>
count(cut, clarity) |>
ggplot() +
facet_wrap(~clarity) +
geom_wedge(color = "blue", alpha = .2) +
aes(amount = n, fill = cut)
last_plot() +
aes(r = 1) # back to unit circle...
Titanic %>%
data.frame() %>%
uncount(Freq) ->
tidyTitanic
tidyTitanic %>%
count(Sex, Survived) %>%
ggplot() +
aes(amount = n, fill = Sex) +
geom_wedge()
last_plot() +
facet_wrap(~Sex)
## Bayesian thinking
# Given Female, prob survived
last_plot() +
aes(fill = Survived)
# Given Survived, prob female
last_plot() +
facet_wrap(~Survived) +
aes(fill = Sex)
last_plot() +
aes(explode = c(0,0, 5, 0))
In fact you get a pie back even without aggregating (something you may notice above; if you look close, the “Survive” Wedges are visible when only Sex is a mapped var…). In the plots here, looking closely, you’ll see the exciting wave patterns that the 2201 wedges create.
Ultimately, we’d want to move to some counting in the background. Amount will be like ‘weight’ in geom_bar()/stat_count()
tidyTitanic %>%
ggplot() +
aes(fill = Sex, amount = 1) +
geom_wedge()
last_plot() +
aes(fill = sort(Sex))
rladies_chapters <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2023/2023-11-21/rladies_chapters.csv')
## Rows: 4268 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (3): chapter, title, location
## dbl (2): id, year
## date (1): date
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
library(tidyverse)
rladies_chapters %>%
filter(year >= 2016) %>%
count(location, year, month = month(date)) %>%
ggplot() +
aes(fill = location, amount = n) +
geom_wedge() +
facet_wrap(~year) +
coord_equal()
last_plot() +
facet_grid(year~month)
library(ggtext)
rladies_chapters %>%
filter(year == 2020) %>%
count(location, month = month(date, label = T, abbr = T)) %>%
ggplot() +
aes(fill = location, amount = n) +
geom_wedge(color = "snow", linewidth = .25) +
facet_wrap(~month, nrow = 2) +
coord_equal() +
labs(fill = NULL) +
ggstamp::theme_void_fill(fill = "snow") +
theme(legend.position = "none",
legend.justification = 0) +
aes(r = 1) + aes(r = NULL) +
scale_fill_manual(values = c("Plum3", "Magenta")) +
labs(title = "RLadies moved from in person to mostly online in 2020") +
theme(plot.title.position = "plot") +
labs(title = "R-Ladies meetings in 2020 moved<br>from mostly <span style = 'color:Plum3;'>in person</span> to mostly <span style = 'color:Magenta;'>online</span>.") +
labs(subtitle = "There was also a drop in the number of April/May meetings.\n") +
theme(
plot.title = element_textbox_simple(
size = 14, lineheight = 1, padding = margin(0, 0, 5, 0)
)
) +
theme(text = element_text(color = "grey55"))
last_plot() +
geom_wedge(aes(label= n), n = 1, geom = "text")