Bar Plot 进阶:环状堆叠条形图

前言

某天,我老妹儿问我:“哥 会画玫瑰堆积图吗?”,自我感觉了一下,应该就是 南丁格尔玫瑰图,在绘图过程中调整一下参数,把position=“dodge2”调整为position = "stack" ,就会变成下图堆叠的效果,好看是毋庸置疑的,但是会给人带来视觉上的误判,因为就视觉效果而言,外圈会看起来似乎更大……(但是挡不住它好看啊)

在这里插入图片描述
后来,坐在工位想了一下,如果有很多相同的实验组对照组,但是不同条件的处理,我又不想画好几张图,那是不是可以这样…这样…然后那样…就可以了😑👌

构建数据

# library
library(tidyverse)
library(viridis)
 
# 创建数据集
data <- data.frame(
  individual=paste( "Mister ", seq(1,60), sep=""),
  group=factor(c( rep('A', 10), rep('B', 30), rep('C', 14), rep('D', 6))) ,
  value1=sample( seq(10,100), 60, replace=T),
  value2=sample( seq(10,100), 60, replace=T),
  value3=sample( seq(10,100), 60, replace=T)
)
 
# 转换为 长格式 ,适配 ggplot
data <- data %>% gather(key = "observation", value="value", -c(1,2))

数据长这样:
在这里插入图片描述

画图(分步骤实现)

以下是解释R代码的要点,:

  • 添加间隔:在数据集的每个组末尾附加无数据的占位符行,以确保清晰的视觉效果。
  • 排序数据:按组和个体重新排列数据集,以保持一致的顺序。
  • 标签:计算显示总值的标签的位置和方向,确保根据其放置位置的可读性。
  • 基线和网格线:设置基线和网格线,为图表提供参考刻度,有助于理解数据的幅度和分布。
  • 构建图表:使用ggplot2创建堆叠、标签和参考线的极坐标条形图。
  • 保存输出:图表导出为PNG文件,设置适当的尺寸以确保清晰度和展示效果。ggsave(p, file = "output.png", width = 10, height = 10)

简单画个带间隔的堆叠 Bar Plot

重塑数据,加上间隔

# 设置要在每组末尾添加的“间隔”数量
empty_bar <- 2
nObsType <- nlevels(as.factor(data$observation))
to_add <- data.frame(matrix(NA, empty_bar * nlevels(data$group) * nObsType, ncol(data)))
colnames(to_add) <- colnames(data)
to_add$group <- rep(levels(data$group), each = empty_bar * nObsType)
data <- rbind(data, to_add)
data <- data %>% arrange(group, individual)
data$id <- rep(seq(1, nrow(data) / nObsType), each = nObsType)

加点细节:在每个间隔的 100/75/50/25 处添加短横线,并添加数字标识

# 准备一个用于基线的数据
base_data <- data %>%
  group_by(group) %>%
  summarize(start = min(id), end = max(id) - empty_bar) %>%
  rowwise() %>%
  mutate(title = mean(c(start, end)))
grid_data <- base_data
grid_data$end <- grid_data$end[c(nrow(grid_data), 1:nrow(grid_data) - 1)] + 1
grid_data$start <- grid_data$start - 1
grid_data <- grid_data[-1, ]

画图

p <- ggplot(data) +
  # 堆叠 Bar
  geom_bar(aes(x = as.factor(id), y = value, fill = observation), stat = "identity", alpha = 0.5) +
  scale_fill_viridis(discrete = TRUE) +
  # 间隔加横线
  geom_segment(data = grid_data, aes(x = end, y = 0, xend = start, yend = 0), colour = "grey", alpha = 1, linewidth = 0.3, inherit.aes = FALSE) +
  geom_segment(data = grid_data, aes(x = end, y = 50, xend = start, yend = 50), colour = "grey", alpha = 1, linewidth = 0.3, inherit.aes = FALSE) +
  geom_segment(data = grid_data, aes(x = end, y = 100, xend = start, yend = 100), colour = "grey", alpha = 1, linewidth = 0.3, inherit.aes = FALSE) +
  geom_segment(data = grid_data, aes(x = end, y = 150, xend = start, yend = 150), colour = "grey", alpha = 1, linewidth = 0.3, inherit.aes = FALSE) +
  geom_segment(data = grid_data, aes(x = end, y = 200, xend = start, yend = 200), colour = "grey", alpha = 1, linewidth = 0.3, inherit.aes = FALSE) +
  # 添加数值标识 100/75/50/25
  ggplot2::annotate("text", x = rep(max(data$id), 5), y = c(0, 50, 100, 150, 200), label = c("0", "50", "100", "150", "200"), color = "grey", size = 6, angle = 0, fontface = "bold", hjust = 1) +
  ylim(-150, max(label_data$tot, na.rm = T)) +
  theme_minimal()

p

在这里插入图片描述

转换坐标系

在每个Bar上边添加标签

# 获取每个标签的名称和y位置
label_data <- data %>%
  group_by(id, individual) %>%
  summarize(tot = sum(value))
number_of_bar <- nrow(label_data)
angle <- 90 - 360 * (label_data$id - 0.5) / number_of_bar
label_data$hjust <- ifelse(angle < -90, 1, 0)
label_data$angle <- ifelse(angle < -90, angle + 180, angle)

画图,加亿点点细节:

p <- p +
  theme(
    legend.position = "none",
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    plot.margin = unit(rep(-1, 4), "cm")
  ) +
  coord_polar() +
  # 在每个Bar的顶部添加标签
  geom_text(data = label_data, aes(x = id, y = tot + 10, label = individual, hjust = hjust), color = "black", fontface = "bold", alpha = 0.6, size = 5, angle = label_data$angle, inherit.aes = FALSE) +
  # 添加信息
  geom_segment(data = base_data, aes(x = start, y = -5, xend = end, yend = -5), colour = "black", alpha = 0.8, size = 0.6, inherit.aes = FALSE) +
  geom_text(data = base_data, aes(x = title, y = -18, label = group), hjust = c(1, 1, 0, 0), colour = "black", alpha = 0.8, size = 4, fontface = "bold", inherit.aes = FALSE)

最后的效果

在这里插入图片描述

完整代码

欢迎关注:wx_gzh 猪猪的乌托邦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值