如何在 R 中使用 'group' 创建分段图表

How to create a segmentation chart with 'group' in R

我有这样的数据集

并且想画一个类似这样的分割图

这将是其中一个组的示例,因此基于数据集,我有组 A 和 B,我想要两个显示所有组的细分图表,每个组都有自己的细分图表显示每个任务开始时间和结束时间,每个任务可能在每个组中出现多次。我有以下用于显示 A 组的代码,对也在同一图表中的子图 B 组有什么建议吗?基本上是如何使用组列来完成图表。 现在图表混合了 A 组和 B 组,但我想区分它们有两个单独的细分图表

category <- c('task1', 'task2', 'task2','task1','task1')
start_min <- c(0, 0, 16, 45, 40)
stop_min <- c(14.9,18.8,17.5,65.5, 70)
group <- c('A', 'B', 'A', 'A', 'B')
data <- data.frame(category,start_min,stop_min,group)



task_bars <- ggplot(data, mapping=aes(ymin=0, ymax=1,
                                      xmin=start_min, xmax=stop_min,
                                      fill=as.factor(category),
                                      text=paste("Task:", str_wrap(string = category, width = 70,),
                                                 "<br>Start: ", format(start_min, digits=1), "min", 
                                                 "<br>Stop: ", format(stop_min, digits=1), "min")
)) +
  geom_rect(alpha=0.8) +
  theme_minimal()+
  theme(
    axis.title.x=element_text(color="white"), axis.text.x=element_text(color="white"),
    axis.text.y=element_blank(), axis.ticks.y=element_blank(),
    panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
    panel.border = element_blank(), panel.background = element_blank()) +
  scale_fill_discrete(breaks=data$category)

task_bars <- plotly::ggplotly(proc_bars, tooltip="text", width = 970, height = 120) %>%
  plotly::config(displayModeBar = TRUE) %>% 
  plotly::layout(plot_bgcolor='black', paper_bgcolor='black', margin = list(b=30, l=0, r=10, t=30))

print(task_bars)

我想到了两种方法。我将分别显示 ggplot 和 plotly 图。

(仅供参考,我假设 proc_bars 实际上只是它之前定义的 task_bars。如果 proc_bars 完全不同,这可能不适用。)

刻面

变化

  • facet_grid(group ~ .) 添加到图
library(ggplot2)
bars1 <- ggplot(data, mapping=aes(ymin=0, ymax=1, xmin=start_min, xmax=stop_min,
                                  fill=as.factor(category))) +
  geom_rect(alpha=0.8) +
  theme_minimal() +
  theme(
    axis.title.x=element_text(color="white"), axis.text.x=element_text(color="white"),
    axis.text.y=element_blank(), axis.ticks.y=element_blank(),
    panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
    panel.border = element_blank(), panel.background = element_blank()) +
    scale_fill_discrete(breaks=data$category) +
  facet_grid(group ~ .)

plotly::ggplotly(bars1, tooltip="text", width = 970, height = 120) %>%
  plotly::config(displayModeBar = TRUE) %>% 
  plotly::layout(plot_bgcolor='black', paper_bgcolor='black', margin = list(b=30, l=0, r=10, t=30))

将“组”移动到y轴

此方法更改为使用 geom_tile,将 group 作为 y 轴。默认值为 height=1,这会将瓷砖放在中间接触;我正在设置 height=0.9 以模仿它们之间的一些间距。

变化:

  • geom_rect 更改为 geom_tile,需要添加 xcenterxwidth
  • 注释掉两个主题元素,使y轴刻度显示
  • 添加labs(y=NULL)隐藏“组”y轴名称,交给你
# this can be done without `dplyr` if desired
data2 <- dplyr::mutate(data, xwidth = stop_min - start_min, xcenter = start_min + xwidth/2)
bars2 <- ggplot(data2, mapping=aes(x=xcenter, y=group, width=xwidth, height=0.9, fill=as.factor(category))) +
  geom_tile(alpha=0.8) +
  theme_minimal() +
  theme(
    axis.title.x=element_text(color="white"), axis.text.x=element_text(color="white"),
    # axis.ticks.y=element_blank(), axis.text.y=element_blank(),
    panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
    panel.border = element_blank(), panel.background = element_blank()) +
  labs(y = NULL) +
  scale_fill_discrete(breaks=data$category)

plotly::ggplotly(bars2, tooltip="text", width = 970, height = 120) %>%
  plotly::config(displayModeBar = TRUE) %>% 
  plotly::layout(plot_bgcolor='black', paper_bgcolor='black', margin = list(b=30, l=0, r=10, t=30))


备注:

  • ggplot2 将按字母顺序对刻面或 y 刻度进行排序;如果您需要任何不同的顺序,请将 group 更改为 factor,并且您必须明确控制 factor(group, levels=***) 级别组件成为您需要的唯一值的顺序。

  • 组的顺序在bars1bars2之间颠倒;这是因为在 bars1 中,切面是从上到下递增的,所以“最少的”在最上面;在 bars2 中,组从底部 (y=1) 递增到顶部 (y=n),因此“最小”在底部;您可以通过多种方式控制它,包括上面的 factor 注解