绘制系统容量的可视化图(管道流量?)

Drawing a visualization of system capacity (pipe flow?)

我需要可靠且可重复地可视化一个系统,该系统就像每单位时间可以通过一定量流体的管道。考虑到工作治疗师的能力,真正的系统是一个具有多种干预措施的治疗部门,每年可以为一定数量的人提供服务。需要可视化,因为人们对数字的反应很差,而我们一直在努力使需求与容量相匹配。

假设有 3 种治疗途径(评估、MBT 和 SCM - 实际上还有更多,但 3 是一个很好的例子)。每个人都有一个等待名单,可以在“管道”打开之前用适当大小的圆圈表示。在职治疗师代表管道的容量——比如每年 24 人或 45 人。当前接受治疗的患者代表管道的填充水平 - 它可以是饱和的或低于饱和的(x%)。

问题:什么是此类问题的良好可视化,哪些 R 包可以帮助实现这一点?

非常感谢您对忙碌的临床医生的建议。 (虽然我对 R 有相当多的经验)

如果您准备好处理数据以使其成为正确的绘图形状,则可以在 ggplot 中完成所有这些操作。以下花了我大约15分钟。

假设您的数据是这样的:

data <- data.frame(service    = c('Assessment', 'MBT', 'SCM'),
                   therapists = c(32, 45, 20),
                   current_patients = c(130, 212, 35),
                   maximum_patients = c(143, 212, 50),
                   queue = c(35, 52, 7))

然后你可以将它重新排列成这样的绘图格式:

library(tidyverse)
library(ggforce)

plot_df <- data %>%
  mutate(left_edge = 10 + c(0, cumsum(head(therapists, -1) + 10)),
         right_edge = cumsum(therapists + 10),
         upper_edge = 80 * current_patients / maximum_patients,
         mid = (left_edge + right_edge) / 2)

然后使用 ggplot 绘制您想要的情节:

ggplot(plot_df) +
  geom_rect(aes(xmin = left_edge, ymin = 0, 
                xmax = right_edge, ymax = upper_edge), fill = 'lightblue') +
  geom_segment(aes(x = left_edge, y = 0, xend = left_edge, yend = 80),
               size = 1, color = 'gray20') +
  geom_segment(aes(x = right_edge, y = 0, xend = right_edge, yend = 80),
               size = 1, color = 'gray20') +
  geom_segment(aes(x = left_edge, y = 0, xend = right_edge, yend = 0),
               size = 1, color = 'gray20') +
  geom_circle(aes(x0 = mid, y0 = 100, r = 2 * sqrt(queue)), fill = '#3070B1',
              color = NA) +
  geom_text(aes(x = mid, y = 100, label = queue), 
            colour = 'white', size = 6, fontface = 2) +
  geom_text(aes(x = mid, y = 40, label = current_patients), 
            size = 6, fontface = 2) +
  geom_text(data = data.frame(x = -30, y = c(10, 40, 100), 
            label = c('Therapists', 'Patients\nIn treatment', 
                      'Patients\nWaiting')),
            aes(x, y, label = label), hjust = 0, size = 6, fontface = 1,
            color = '#202040') +
  geom_segment(aes(x = mid, y = 10, xend = left_edge, yend = 10),
               arrow = arrow(length = unit(0.1, 'inches'))) +
  geom_segment(aes(x = mid, y = 10, xend = right_edge, yend = 10),
               arrow = arrow(length = unit(0.1, 'inches'))) +
  geom_label(aes(x = mid, y = 10, label = therapists), fontface = 2) +
  scale_x_continuous(breaks = plot_df$mid, labels = plot_df$service,
                     limits = c(-30, 140)) +
  coord_equal() +
  theme_void() +
  theme(axis.text.x = element_text(size = 18, color = '#202040'),
        plot.background = element_rect(fill = '#f3f9ff'),
        plot.margin = margin(50, 20, 50, 20))