5 常用图形
library(tidyverse)
library(ggExtra)
library(ragg)
library(ggalluvial)
library(treemapify)
library(ggalt)
library(palmerpenguins)
head(penguins)
## # A tibble: 6 × 8
## species island bill_length_mm bill_depth_mm flipper_length_… body_mass_g sex
## <fct> <fct> <dbl> <dbl> <int> <int> <fct>
## 1 Adelie Torge… 39.1 18.7 181 3750 male
## 2 Adelie Torge… 39.5 17.4 186 3800 fema…
## 3 Adelie Torge… 40.3 18 195 3250 fema…
## 4 Adelie Torge… NA NA NA NA <NA>
## 5 Adelie Torge… 36.7 19.3 193 3450 fema…
## 6 Adelie Torge… 39.3 20.6 190 3650 male
## # … with 1 more variable: year <int>
#head(penguins_raw)
# The palette with grey:
<- c("#999999", "#E69F00", "#56B4E9", "#009E73",
cbp1 "#F0E442", "#0072B2", "#D55E00", "#CC79A7")
# The palette with black:
<- c("#000000", "#E69F00", "#56B4E9", "#009E73",
cbp2 "#F0E442", "#0072B2", "#D55E00", "#CC79A7")
library(plotrix)
<- rep(10, 8) # each slice value=10 for proportionate slices
sliceValues
(<- pie3D(sliceValues,
p explode=0,
theta = 1.2,
col = cbp1,
labels = cbp1,
labelcex = 0.9,
shade = 0.6,
main = "Colorblind\nfriendly palette")
)
## [1] 0.3926991 1.1780972 1.9634954 2.7488936 3.5342917 4.3196899 5.1050881
## [8] 5.8904862
<- function(...) ggplot2::ggplot(...) +
ggplot scale_color_manual(values = cbp1) +
scale_fill_manual(values = cbp1) + # note: needs to be overridden when using continuous color scales
theme_bw()
penguins
## # A tibble: 344 × 8
## species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
## <fct> <fct> <dbl> <dbl> <int> <int>
## 1 Adelie Torgersen 39.1 18.7 181 3750
## 2 Adelie Torgersen 39.5 17.4 186 3800
## 3 Adelie Torgersen 40.3 18 195 3250
## 4 Adelie Torgersen NA NA NA NA
## 5 Adelie Torgersen 36.7 19.3 193 3450
## 6 Adelie Torgersen 39.3 20.6 190 3650
## 7 Adelie Torgersen 38.9 17.8 181 3625
## 8 Adelie Torgersen 39.2 19.6 195 4675
## 9 Adelie Torgersen 34.1 18.1 193 3475
## 10 Adelie Torgersen 42 20.2 190 4250
## # … with 334 more rows, and 2 more variables: sex <fct>, year <int>
<- penguins %>%
penguins_long gather("key", "value", bill_length_mm:body_mass_g)
%>%
penguins group_by(species) %>%
count(sex) %>%
arrange(desc(n))
## # A tibble: 8 × 3
## # Groups: species [3]
## species sex n
## <fct> <fct> <int>
## 1 Adelie female 73
## 2 Adelie male 73
## 3 Gentoo male 61
## 4 Gentoo female 58
## 5 Chinstrap female 34
## 6 Chinstrap male 34
## 7 Adelie <NA> 6
## 8 Gentoo <NA> 5
%>%
penguins gather("key", "value", bill_length_mm:body_mass_g) %>%
group_by(species, sex, island, key) %>%
summarise(n = n(),
sum = sum(value),
mean = mean(value),
median = median(value),
sd = sd(value),
se = sd(value) / sqrt(n()))
## # A tibble: 52 × 10
## # Groups: species, sex, island [13]
## species sex island key n sum mean median sd se
## <fct> <fct> <fct> <chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Adelie female Biscoe bill_dept… 22 389. 17.7 17.7 1.09 0.233
## 2 Adelie female Biscoe bill_leng… 22 822. 37.4 37.8 1.76 0.376
## 3 Adelie female Biscoe body_mass… 22 74125 3369. 3375 343. 73.2
## 4 Adelie female Biscoe flipper_l… 22 4118 187. 187 6.74 1.44
## 5 Adelie female Dream bill_dept… 27 476. 17.6 17.8 0.897 0.173
## 6 Adelie female Dream bill_leng… 27 997. 36.9 36.8 2.09 0.402
## 7 Adelie female Dream body_mass… 27 90300 3344. 3400 212. 40.8
## 8 Adelie female Dream flipper_l… 27 5072 188. 188 5.51 1.06
## 9 Adelie female Torgersen bill_dept… 24 421. 17.6 17.4 0.880 0.180
## 10 Adelie female Torgersen bill_leng… 24 901. 37.6 37.6 2.21 0.451
## # … with 42 more rows
%>%
penguins group_by(species, sex, island, year) %>%
summarise_each(funs(sum,
mean,
median,
sd, se = sd(.) / sqrt(n())
) )
## # A tibble: 35 × 24
## # Groups: species, sex, island [13]
## species sex island year bill_length_mm_… bill_depth_mm_s… flipper_length_…
## <fct> <fct> <fct> <int> <dbl> <dbl> <int>
## 1 Adelie fema… Biscoe 2007 187. 92.9 909
## 2 Adelie fema… Biscoe 2008 330. 155 1679
## 3 Adelie fema… Biscoe 2009 305. 142. 1530
## 4 Adelie fema… Dream 2007 341. 161. 1665
## 5 Adelie fema… Dream 2008 290. 142. 1512
## 6 Adelie fema… Dream 2009 366. 173. 1895
## 7 Adelie fema… Torge… 2007 306. 145. 1501
## 8 Adelie fema… Torge… 2008 293. 139. 1520
## 9 Adelie fema… Torge… 2009 302. 137. 1498
## 10 Adelie male Biscoe 2007 196. 91.5 908
## # … with 25 more rows, and 17 more variables: body_mass_g_sum <int>,
## # bill_length_mm_mean <dbl>, bill_depth_mm_mean <dbl>,
## # flipper_length_mm_mean <dbl>, body_mass_g_mean <dbl>,
## # bill_length_mm_median <dbl>, bill_depth_mm_median <dbl>,
## # flipper_length_mm_median <dbl>, body_mass_g_median <dbl>,
## # bill_length_mm_sd <dbl>, bill_depth_mm_sd <dbl>,
## # flipper_length_mm_sd <dbl>, body_mass_g_sd <dbl>, …
5.1 散点图
%>%
penguins remove_missing() %>%
ggplot(aes(x = bill_length_mm, y = flipper_length_mm, color = species)) +
geom_jitter(alpha = 0.5) +
#facet_wrap(vars(species), ncol = 3) +
#scale_x_reverse() +
#scale_y_reverse() +
labs(x = "Bill length (mm)",
y = "Flipper length (mm)",
size = "body mass (g)",
title = "Scatterplot",
subtitle = "Penguins bill v. flipper length by species",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
%>%
penguins remove_missing() %>%
ggplot(aes(x = bill_length_mm, y = flipper_length_mm,
color = species, shape = species)) +
geom_point(alpha = 0.7) +
labs(x = "Bill length (mm)",
y = "Flipper length (mm)",
title = "Scatterplot",
subtitle = "Penguins bill v. flipper length by species",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
- with labels/text
<- penguins %>%
max_lables remove_missing() %>%
group_by(species, island) %>%
summarise(bill_length_mm = max(bill_length_mm),
flipper_length_mm = max(flipper_length_mm))
%>%
penguins remove_missing() %>%
ggplot(aes(x = bill_length_mm, y = flipper_length_mm,
color = species, shape = species)) +
geom_point(alpha = 0.7) +
geom_text(data = max_lables, aes(label = island)) +
labs(x = "Bill length (mm)",
y = "Flipper length (mm)",
title = "Scatterplot",
subtitle = "Penguins bill v. flipper length by species",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
- Jitter with smoothing line
%>%
penguins remove_missing() %>%
ggplot(aes(x = bill_length_mm, y = flipper_length_mm,
color = species, shape = species)) +
geom_jitter(alpha = 0.5) +
geom_smooth(method = "loess", se = TRUE) +
facet_wrap(vars(species), nrow = 3) +
labs(x = "Bill length (mm)",
y = "Flipper length (mm)",
title = "Scatterplot with smoothing line",
subtitle = "Penguins bill v. flipper length by species with loess smoothing line",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
%>%
penguins remove_missing() %>%
filter(species == "Adelie") %>%
ggplot(aes(x = bill_length_mm, y = flipper_length_mm)) +
geom_point(alpha = 0.5) +
geom_smooth(method = "loess", se = TRUE) +
labs(x = "Bill length (mm)",
y = "Flipper length (mm)",
title = "Scatterplot with smoothing line",
subtitle = "Penguins bill v. flipper length by species with\nloess smoothing line, histogram & density distribution",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
#(ggMarginal(p, type = "densigram", fill = "transparent"))
5.2 气泡图
%>%
penguins remove_missing() %>%
ggplot(aes(x = bill_length_mm, y = flipper_length_mm,
color = species, shape = species, size = body_mass_g)) +
geom_point(alpha = 0.5) +
labs(x = "Bill length (mm)",
y = "Flipper length (mm)",
title = "Bubble plot",
size = "body mass (g)",
subtitle = "Penguins bill v. flipper length by species;\nsize indicates body mass in grams",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.3 线性图
%>%
penguins remove_missing() %>%
filter(species == "Adelie") %>%
ggplot(aes(x = bill_length_mm, y = flipper_length_mm,
color = sex)) +
geom_line() +
geom_point() +
labs(x = "Bill length (mm)",
y = "Flipper length (mm)",
title = "Line plot",
subtitle = "Penguins bill v. flipper length by species and sex",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.4 相关系数图/热力图
<- penguins %>%
mat remove_missing() %>%
select(bill_depth_mm, bill_length_mm, body_mass_g, flipper_length_mm)
str(mat)
## tibble [333 × 4] (S3: tbl_df/tbl/data.frame)
## $ bill_depth_mm : num [1:333] 18.7 17.4 18 19.3 20.6 17.8 19.6 17.6 21.2 21.1 ...
## $ bill_length_mm : num [1:333] 39.1 39.5 40.3 36.7 39.3 38.9 39.2 41.1 38.6 34.6 ...
## $ body_mass_g : int [1:333] 3750 3800 3250 3450 3650 3625 4675 3200 3800 4400 ...
## $ flipper_length_mm: int [1:333] 181 186 195 193 190 181 195 182 191 198 ...
<- round(cor(mat), 2)
cormat upper.tri(cormat)] <- NA
cormat[
<- cormat %>%
cormat as_data_frame() %>%
mutate(x = colnames(mat)) %>%
gather(key = "y", value = "value", bill_depth_mm:flipper_length_mm)
%>%
cormat remove_missing() %>%
arrange(x, y) %>%
ggplot(aes(x = x, y = y, fill = value)) +
geom_tile() +
scale_fill_gradient2(low = "blue", high = "red", mid = "white",
midpoint = 0, limit = c(-1,1), space = "Lab",
name = "Pearson\nCorrelation") +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
coord_fixed() +
labs(x = "",
y = "",
title = "Correlation heatmap",
subtitle = "Correlation btw. penguins' traits",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.5 条形图
- per default: counts
%>%
penguins remove_missing() %>%
ggplot(aes(x = species,
fill = sex)) +
geom_bar() +
labs(x = "Species",
y = "Counts",
title = "Barchart",
subtitle = "Counts of male & female penguins per species in study",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
%>%
penguins remove_missing() %>%
ggplot(aes(x = species,
fill = sex)) +
geom_bar(position = 'dodge') +
labs(x = "Species",
y = "Counts",
title = "Barchart",
subtitle = "Counts of male & female penguins per species in study",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
- alternative: set y-values
%>%
penguins remove_missing() %>%
group_by(species, sex) %>%
summarise(mean_bmg = mean(body_mass_g),
sd_bmg = sd(body_mass_g)) %>%
ggplot(aes(x = species, y = mean_bmg,
fill = sex)) +
geom_bar(stat = "identity", position = "dodge") +
geom_errorbar(aes(ymin = mean_bmg - sd_bmg,
ymax = mean_bmg + sd_bmg),
width = 0.2,
position = position_dodge(0.9)) +
labs(x = "Species",
y = "Mean body mass (in g)",
title = "Barchart",
subtitle = "Mean body mass of male & female penguins per species\nwith standard deviation",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
library(plotly)
<- penguins %>%
p remove_missing() %>%
group_by(species, sex) %>%
summarise(mean_bmg = mean(body_mass_g),
sd_bmg = sd(body_mass_g)) %>%
ggplot(aes(x = species, y = mean_bmg,
fill = sex)) +
geom_bar(stat = "identity", position = "dodge") +
geom_errorbar(aes(ymin = mean_bmg - sd_bmg,
ymax = mean_bmg + sd_bmg),
width = 0.2,
position = position_dodge(0.9)) +
labs(x = "Species",
y = "Mean body mass (in g)",
title = "Barchart",
subtitle = "Mean body mass of male & female penguins per species\nwith standard deviation",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
ggplotly(p)
5.6 箱线图
<- penguins %>%
pp remove_missing() %>%
ggplot(aes(x = species, y = body_mass_g,
fill = sex)) +
geom_boxplot() +
labs(x = "Species",
y = "Body mass (in g)",
title = "Boxplot",
subtitle = "Body mass of three penguin species per sex",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
ggplotly(pp)
- with points
%>%
penguins remove_missing() %>%
ggplot(aes(x = species, y = body_mass_g,
fill = sex, color = sex)) +
geom_boxplot(alpha = 0.5, notch = TRUE) +
geom_jitter(alpha = 0.5, position=position_jitter(0.3)) +
labs(x = "Species",
y = "Body mass (in g)",
title = "Boxplot with points (dotplot)",
subtitle = "Body mass of three penguin species per sex",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.7 小提琴图
%>%
penguins remove_missing() %>%
ggplot(aes(x = species, y = body_mass_g,
fill = sex)) +
geom_violin(scale = "area") +
labs(x = "Species",
y = "Body mass (in g)",
title = "Violinplot",
subtitle = "Body mass of three penguin species per sex",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
- with dots (sina-plots)
%>%
penguins remove_missing() %>%
ggplot(aes(x = species, y = body_mass_g,
fill = sex, color = sex)) +
geom_dotplot(method = "dotdensity", alpha = 0.7,
binaxis = 'y', stackdir = 'center',
position = position_dodge(1)) +
labs(x = "Species",
y = "Body mass (in g)",
title = "Violinplot with points (dotplot)",
subtitle = "Body mass of three penguin species per sex",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.8 饼图
%>%
penguins remove_missing() %>%
group_by(species, sex) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n),
percentage = freq * 100) %>%
ggplot(aes(x = "", y = percentage,
fill = sex)) +
facet_wrap(vars(species), nrow = 1) +
geom_bar(stat = "identity", alpha = 0.8) +
coord_polar("y", start = 0) +
labs(x = "",
y = "Percentage",
title = "Piechart",
subtitle = "Percentage of male v. female penguins per species in study",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.9 冲积图
as.data.frame(UCBAdmissions) %>%
ggplot(aes(y = Freq, axis1 = Gender, axis2 = Dept)) +
geom_alluvium(aes(fill = Admit), width = 1/12) +
geom_stratum(width = 1/12, fill = "black", color = "grey") +
geom_label(stat = "stratum", aes(label = after_stat(stratum))) +
scale_x_discrete(limits = c("Gender", "Dept"), expand = c(.05, .05)) +
labs(x = "",
y = "Frequency",
title = "Alluvial chart",
subtitle = "UC Berkeley admissions and rejections, by sex and department",
caption = "Source: Bickel et al. (1975)\nSex bias in graduate admissions: Data from Berkeley. Science, 187, 398–403.")
5.10 系谱图
as.data.frame(UCBAdmissions) %>%
group_by(Admit, Gender) %>%
summarise(sum_freq = sum(Freq)) %>%
ggplot(aes(area = sum_freq, fill = sum_freq, label = Gender,
subgroup = Admit)) +
geom_treemap() +
geom_treemap_subgroup_border() +
geom_treemap_subgroup_text(place = "centre", grow = T, alpha = 0.5, colour =
"black", fontface = "italic", min.size = 0) +
geom_treemap_text(colour = "white", place = "centre", reflow = T) +
scale_fill_gradient2(low = "#999999", high = "#E69F00", mid = "white", midpoint = 1000, space = "Lab",
name = "Sum of\nfrequencies") +
labs(x = "",
y = "",
title = "Treemap",
subtitle = "UC Berkeley admissions and rejections by sex",
caption = "Source: Bickel et al. (1975)\nSex bias in graduate admissions: Data from Berkeley. Science, 187, 398–403.")
5.11 哑铃图
%>%
penguins remove_missing() %>%
group_by(year, species, sex) %>%
summarise(mean_bmg = mean(body_mass_g)) %>%
mutate(species_sex = paste(species, sex, sep = "_"),
year = paste0("year_", year)) %>%
spread(year, mean_bmg) %>%
ggplot(aes(x = year_2007, xend = year_2009,
y = reorder(species_sex, year_2009))) +
geom_dumbbell(color = "#999999",
size_x = 3,
size_xend = 3,
#Note: there is no US:'color' for UK:'colour'
# in geom_dumbbel unlike standard geoms in ggplot()
colour_x = "#999999",
colour_xend = "#E69F00") +
labs(x = "Body mass (g)",
y = "Species & sex",
title = "Dumbbell plot",
subtitle = "Penguin's change in body mass from 2007 to 2009",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.12 斜率图
%>%
penguins remove_missing() %>%
group_by(year, species, sex) %>%
summarise(mean_bmg = mean(body_mass_g)) %>%
ggplot(aes(x = year, y = mean_bmg, group = sex,
color = sex)) +
facet_wrap(vars(species), nrow = 3) +
geom_line(alpha = 0.6, size = 2) +
geom_point(alpha = 1, size = 3) +
scale_x_continuous(breaks=c(2007, 2008, 2009)) +
labs(x = "Year",
y = "Body mass (g)",
color = "Sex",
title = "Slope chart",
subtitle = "Penguin's change in body mass from 2007 to 2009",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.13 堆叠面积图
%>%
penguins remove_missing() %>%
group_by(year, species, sex) %>%
summarise(mean_bmg = mean(body_mass_g)) %>%
ggplot(aes(x = year, y = mean_bmg, fill = sex)) +
facet_wrap(vars(species), nrow = 3) +
geom_area(alpha = 0.6, size=.5, color = "white") +
scale_x_continuous(breaks=c(2007, 2008, 2009)) +
labs(x = "Year",
y = "Mean body mass (g)",
color = "Sex",
title = "Stacked area chart",
subtitle = "Penguin's change in body mass from 2007 to 2009",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.14 棒棒糖图
%>%
penguins remove_missing() %>%
group_by(year, species, sex) %>%
summarise(mean_bmg = mean(body_mass_g)) %>%
mutate(species_sex = paste(species, sex, sep = "_"),
year = paste0("year_", year)) %>%
spread(year, mean_bmg) %>%
ggplot() +
geom_segment(aes(x = reorder(species_sex, -year_2009), xend = reorder(species_sex, -year_2009),
y = 0, yend = year_2009),
color = "#999999", size = 1) +
geom_point(aes(x = reorder(species_sex, -year_2009), y = year_2009),
size = 4, color = "#E69F00") +
coord_flip() +
labs(x = "Species & sex",
y = "Body mass (g)",
title = "Lollipop chart",
subtitle = "Penguin's body mass in 2009",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.15 树状图
library(ggdendro)
library(dendextend)
<- penguins %>%
penguins_hist filter(sex == "male") %>%
select(species, bill_length_mm, bill_depth_mm, flipper_length_mm, body_mass_g) %>%
group_by(species) %>%
sample_n(10) %>%
as.data.frame()
rownames(penguins_hist) <- paste(penguins_hist$species, seq_len(nrow(penguins_hist)), sep = "_")
<- penguins_hist %>%
penguins_hist select(-species) %>%
remove_missing()
<- hclust(dist(penguins_hist, method = "euclidean"), method = "ward.D2")
hc ggdendrogram(hc)
# Create a dendrogram and plot it
%>%
penguins_hist %>%
scale dist(method = "euclidean") %>%
hclust(method = "ward.D2") %>%
as.dendrogram() %>%
plot()
5.16 瀑布图
library(waterfall)
%>%
jaquith arrange(score) %>%
add_row(factor = "Total", score = sum(jaquith$score)) %>%
mutate(factor = factor(factor, levels = factor),
id = seq_along(score)) %>%
mutate(end = cumsum(score),
start = c(0, end[-length(end)]),
start = c(start[-length(start)], 0),
end = c(end[-length(end)], score[length(score)]),
gr_col = ifelse(factor == "Total", "Total", "Part")) %>%
ggplot(aes(x = factor, fill = gr_col)) +
geom_rect(aes(x = factor,
xmin = id - 0.45, xmax = id + 0.45,
ymin = end, ymax = start)) +
theme(axis.text.x = element_text(angle = 60, vjust = 1, hjust = 1),
legend.position = "none") +
labs(x = "",
y = "Amount",
title = "Waterfall chart",
subtitle = "Sample business-adjusted risk from Security Metrics",
caption = "Andrew Jaquith, Security Metrics: Replacing Fear, Uncertainty, and Doubt\n(Boston: Addison-Wesley Professional, 2007), 170-171.")
5.17 双标图
library(ggfortify)
<- penguins %>%
penguins_prep remove_missing() %>%
select(bill_length_mm:body_mass_g)
<- penguins_prep %>%
penguins_pca prcomp(scale. = TRUE)
<- penguins_prep %>%
penguins_km kmeans(3)
autoplot(penguins_pca,
data = penguins %>% remove_missing(),
colour = 'species',
shape = 'species',
loadings = TRUE,
loadings.colour = 'blue',
loadings.label = TRUE,
loadings.label.size = 3) +
scale_color_manual(values = cbp1) +
scale_fill_manual(values = cbp1) +
theme_bw() +
labs(
title = "Biplot PCA",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
autoplot(penguins_km,
data = penguins %>% remove_missing(),
colour = 'species',
shape = 'species',
frame = TRUE, frame.type = 'norm') +
scale_color_manual(values = cbp1) +
scale_fill_manual(values = cbp1) +
theme_bw() +
labs(
title = "Biplot k-Means clustering",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")
5.18 雷达图/星图/蜘蛛图
https://www.data-to-viz.com/caveat/spider.html
library(ggiraphExtra)
%>%
penguins remove_missing() %>%
select(-island, -year) %>%
ggRadar(aes(x = c(bill_length_mm, bill_depth_mm, flipper_length_mm, body_mass_g),
group = species,
colour = sex, facet = sex),
rescale = TRUE,
size = 1, interactive = FALSE,
use.label = TRUE) +
scale_color_manual(values = cbp1) +
scale_fill_manual(values = cbp1) +
theme_bw() +
scale_y_discrete(breaks = NULL) + # don't show ticks
labs(
title = "Radar/spider/star chart",
subtitle = "Body mass of male & female penguins per species",
caption = "Source: https://github.com/allisonhorst/palmerpenguins")