ggpol包优雅的绘制蝴蝶图

2023-10-24 14:05:12 浏览数 (2)

欢迎关注R语言数据分析指南

加载R包

代码语言:javascript复制
library(tidyverse)
# devtools::install_github('erocoar/ggpol')
library(ggpol)

导入数据

代码语言:javascript复制
df <- read_tsv("data.xls")

数据清洗

代码语言:javascript复制
results <- df %>%
  group_by(constituency, gender, status) %>%  # 分组处理
  summarise(count = sum(count)) %>%  # 计算每组的数量
  ungroup() %>%  # 解除分组
  unite(col = "status_gender", gender, status, sep = "_") %>%  # 将性别和选举状态合并成一个新的列
  pivot_wider(names_from = status_gender, values_from = count) %>%  # 长表转宽表
  mutate(ratio = female_elected / male_elected) %>%  # 统计性别比率
  gather(key = category, value = count, -constituency, -ratio) %>%  # 宽表转长表
  separate(category, into = c("gender", "status")) %>%  # 将category列分成性别和状态两列
  uncount(count) %>%  # 根据count列的值,将行复制相应的次数
  group_by(constituency, gender) %>%  
  mutate(y = sequence(n())) %>%  # 为每组生成一个序列号
  mutate(y = ifelse(gender == "female", -y, y)) %>%  # 如果是女性,将序列号取反
  ungroup() %>%  # 解除分组
  mutate(status_label = case_when(status == "elected" ~ "elected", 
                                  status == "notelected" ~ "not elected"),
         gender_label = case_when(gender == "female" ~ "Female candidates",  # 添加性别标签
                                  gender == "male" ~ "Male candidates"),
         dominant_gender = case_when(status == "notelected" ~ "not elected",  # 添加主导性别标签
                                     status == "elected" & ratio > 1 ~ "Female majority elected",
                                     status == "elected" & ratio < 1 ~ "Male majority elected",
                                     status == "elected" & ratio == 1 ~ "Gender balance")) %>%
  mutate_if(is.character, factor)  # 将字符列转换为因子

构建数据用于在图形中添加空白区域

代码语言:javascript复制
dummy_constituency = 
  tibble(y = c(-max(results$y), 0, 0, max(results$y)),  # y值为最大最小值及其负值
         gender = c("female", "female", "male", "male")) %>%  # 性别列
  mutate(gender_label = case_when(gender == "female" ~ "Female candidates",  # 添加性别标签
                                  gender == "male" ~ "Male candidates"))

数据可视化

代码语言:javascript复制
ggplot()  
  geom_point(data = results,  # 添加点图层,使用处理后的选举数据
             mapping = aes(x = constituency,y = y,color = dominant_gender),  # 映射选区、y值和主导性别
             shape = 19,size = 4)  
  geom_blank(data = dummy_constituency,  # 添加空白图层,使用虚拟选区数据
             mapping = aes(y = y))  
  ggpol::facet_share(~ gender_label, dir = "h", scales = "free", reverse_num = TRUE)    # 分面显示,根据性别标签分面
  coord_flip()    # 翻转坐标轴,使选区显示在y轴
  scale_x_discrete(name = NULL,expand = c(0,1),  # 调整x轴比例和标签
                   limits = rev(levels(results$constituency)))  
  scale_y_continuous(name = NULL, breaks = NULL,expand = c(0,1))    # 调整y轴比例和标签
  scale_color_manual(name = NULL, values = c("indianred2", "palegreen3", "skyblue2", "grey87"))    # 手动设置颜色
  theme(panel.grid = element_blank(),  # 调整图形主题
        legend.position = "bottom",
        strip.text = element_text(size = 12),
        legend.text = element_text(size = 10),
        plot.background = element_blank(),
        panel.background = element_blank(),
        strip.background = element_blank(),
        legend.background = element_blank(),
        legend.key = element_blank(),
        legend.spacing.x = unit(0,"cm"),
        plot.margin = margin(0.2,0.2,1,-100))

0 人点赞