You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用R将婴儿24小时睡眠喂养数据可视化为时钟式饼图或条形图

婴儿睡眠与喂养时段可视化方案

需求说明

出于研究需求,需追踪婴儿24小时内的睡眠与喂养时段,实现以下可视化效果:

  • 极坐标时钟图(环形饼图):绿色代表喂养时段,蓝色代表睡眠时段,时段间用白色间隙分隔
  • 水平条形图(时间轴样式)
  • 欢迎其他可视化思路补充

已通过lubridate包完成数据预处理,将时间转换为datetime格式并拆分跨午夜的时段,预处理代码如下:

library(tidyverse)
library(lubridate) 

df <- data.frame(
  date = c("2025-08-30", "2025-08-30", "2025-08-30", "2025-08-30", "2025-08-30", "2025-08-30", "2025-08-30", "2025-08-30", "2025-08-30"),
  activity = c("sleep", "feed", "sleep", "feed", "sleep", "feed", "sleep", "feed", "sleep"),
  start_time = c("1:00 AM", "2:30 AM", "3:00 AM", "6:15 AM", "8:00 AM", "11:00 AM", "1:20 PM", "6:00 PM", "8:00 PM"),
  end_time   = c("2:30 AM", "2:40 AM", "6:00 AM", "6:30 AM", "9:30 AM", "11:24 AM", "3:40 PM", "7:00 PM", "2:00 AM")
)

# 标记跨午夜时段
df = df %>% 
  mutate(midnight_flag = if_else(
    str_detect(start_time, "PM") & str_detect(end_time, "AM"), TRUE, FALSE),
    start_time = str_c(date, " ", start_time) %>% ymd_hm(),
    end_time = str_c(date, " ", end_time) %>% ymd_hm()) %>% 
  mutate(end_time = if_else(
    midnight_flag == TRUE,
    end_time + days(1),
    end_time
  )) 

# 拆分跨午夜的时段为两行
df = df %>%
  split(seq_len(nrow(.))) %>% 
  map_dfr(function(row) {
    if (row$midnight_flag) {
      midnight <- ceiling_date(row$start_time, unit = "day")
      tibble(
        activity = row$activity,
        date = c(as_date(row$start_time), as_date(midnight)),
        start_time = c(row$start_time, midnight),
        end_time = c(midnight, row$end_time)
      )
    } else {
      tibble(
        activity = row$activity,
        date = as_date(row$start_time),
        start_time = row$start_time,
        end_time = row$end_time)}})

可视化实现

1. 极坐标时钟图(24小时环形)

该方案模拟24小时时钟样式,用环形区块展示不同时段的活动,通过白色间隙区分相邻活动。

数据准备

先将时间转换为一天内的小时数,添加间隙占位行:

# 转换为一天内的小时数,计算时长
df_plot <- df %>%
  mutate(
    start_hour = hour(start_time) + minute(start_time)/60,
    end_hour = hour(end_time) + minute(end_time)/60,
    duration = end_hour - start_hour
  ) %>%
  # 筛选目标日期(示例为2025-08-30)
  filter(date == ymd("2025-08-30"))

# 添加时段间隙:每个活动结束后加0.1小时的空白(可根据需求调整宽度)
gap_rows <- df_plot %>%
  mutate(
    activity = "gap",
    start_hour = end_hour,
    end_hour = end_hour + 0.1,
    duration = 0.1
  ) %>%
  # 确保间隙不超过24小时边界
  mutate(end_hour = ifelse(end_hour > 24, 24, end_hour),
         duration = end_hour - start_hour)

# 合并活动与间隙数据,按时间排序
df_with_gaps <- bind_rows(df_plot, gap_rows) %>%
  arrange(start_hour) %>%
  filter(start_hour < 24)

绘图代码

# 定义颜色映射:蓝色睡眠、绿色喂养、白色间隙
color_map <- c("sleep" = "#4a90e2", "feed" = "#50c878", "gap" = "white")

ggplot(df_with_gaps, aes(xmin = 0, xmax = 1, ymin = start_hour, ymax = end_hour, fill = activity)) +
  geom_rect(color = "white", size = 0.5) + # 白色边框强化间隙效果
  coord_polar(theta = "y", start = -pi/2) + # 极坐标布局,0点(午夜)位于顶部
  scale_y_continuous(
    breaks = seq(0,24,3), 
    labels = c("00:00", "03:00", "06:00", "09:00", "12:00", "15:00", "18:00", "21:00", "24:00")
  ) +
  scale_fill_manual(values = color_map) +
  theme_minimal() +
  theme(
    axis.title = element_blank(),
    panel.grid = element_blank(),
    axis.text.y = element_text(size = 10),
    legend.position = "bottom",
    legend.title = element_blank()
  ) +
  labs(title = "婴儿24小时睡眠与喂养时段")

2. 水平条形图(时间轴样式)

该方案用横向条形直观展示一天内的活动时段,适合快速查看时间分布。

ggplot(df_plot, aes(xmin = start_hour, xmax = end_hour, ymin = 0.8, ymax = 1.2, fill = activity)) +
  geom_rect(color = "white", size = 1) + # 白色边框区分相邻活动
  scale_x_continuous(
    breaks = seq(0,24,2), 
    labels = paste0(seq(0,24,2), ":00"), 
    limits = c(0,24)
  ) +
  scale_fill_manual(values = c("sleep" = "#4a90e2", "feed" = "#50c878")) +
  theme_minimal() +
  theme(
    axis.title.x = element_text(label = "时间"),
    axis.title.y = element_blank(),
    axis.text.y = element_blank(),
    panel.grid.y = element_blank(),
    legend.position = "bottom",
    legend.title = element_blank(),
    axis.ticks.y = element_blank()
  ) +
  labs(title = "婴儿24小时睡眠与喂养时段")

3. 其他可视化思路

热力图(时段密集度展示)

将一天划分为15分钟的时间块,用颜色标记每个块的活动类型,直观展示时段分布:

# 生成15分钟间隔的时间网格
time_grid <- tibble(
  time = seq(ymd_hm("2025-08-30 00:00"), ymd_hm("2025-08-30 23:45"), by = "15 mins"),
  hour_block = hour(time) + minute(time)/60
)

# 匹配每个时间块对应的活动
time_grid <- time_grid %>%
  left_join(df_plot, by = character()) %>%
  filter(hour_block >= start_hour & hour_block < end_hour) %>%
  select(time, activity) %>%
  distinct(time, .keep_all = TRUE)

# 绘制热力图
ggplot(time_grid, aes(x = hour(time) + minute(time)/60, y = 1, fill = activity)) +
  geom_tile(width = 0.25, height = 1) + # 15分钟对应0.25小时宽度
  scale_x_continuous(
    breaks = seq(0,24,2), 
    labels = paste0(seq(0,24,2), ":00"), 
    limits = c(0,24)
  ) +
  scale_fill_manual(values = c("sleep" = "#4a90e2", "feed" = "#50c878")) +
  theme_minimal() +
  theme(
    axis.title.x = element_text(label = "时间"),
    axis.title.y = element_blank(),
    axis.text.y = element_blank(),
    panel.grid = element_blank(),
    legend.position = "bottom",
    legend.title = element_blank()
  ) +
  labs(title = "婴儿24小时睡眠与喂养热力图(15分钟间隔)")

交互式可视化(plotly)

将极坐标图或条形图转为交互式,支持鼠标悬停查看具体时段信息:

library(plotly)

# 基于极坐标图生成交互式版本
p <- ggplot(df_with_gaps, aes(xmin = 0, xmax = 1, ymin = start_hour, ymax = end_hour, fill = activity,
                              text = paste0(activity, "\n开始时间: ", format(start_time, "%H:%M"), "\n结束时间: ", format(end_time, "%H:%M")))) +
  geom_rect(color = "white", size = 0.5) +
  coord_polar(theta = "y", start = -pi/2) +
  scale_y_continuous(breaks = seq(0,24,3), labels = c("00:00", "03:00", "06:00", "09:00", "12:00", "15:00", "18:00", "21:00", "24:00")) +
  scale_fill_manual(values = color_map) +
  theme_minimal() +
  theme(axis.title = element_blank(), panel.grid = element_blank(), axis.text.y = element_text(size = 10), legend.position = "bottom", legend.title = element_blank()) +
  labs(title = "婴儿24小时睡眠与喂养时段")

# 转为交互式图表
ggplotly(p, tooltip = "text")

内容的提问来源于stack exchange,提问作者user3710004

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 02:43:15