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

如何用ggplot2绘制跨天24小时时钟的散点图?

解决无日期24小时时间散点图的Y轴冗余标签问题

问题说明

使用tidyverse v1.3.2生成数据的代码如下:

submits <- tibble::tribble(
  ~ id, ~ submission, ~ day,
  1, "18:25:12", 2,
  2, "01:37:40", 3,
  3, "11:40:50", 2, 
  4, "00:55:00", 2
)

生成的数据集:

# A tibble: 4 × 3
     id submission   day
  <dbl> <chr>      <dbl>
1     1 18:25:12       2
2     2 01:37:40       3
3     3 11:40:50       2
4     4 00:55:00       2

其中submission列是无日期的24小时制提交时间,day列代表参考日期到提交日期的间隔天数。尝试绘制以day为横轴、submission为纵轴的散点图时,使用以下代码会导致Y轴出现冗余的00:00标签,显示效果不佳:

submits %>%
  mutate(submission = as.POSIXct(submission, format = "%H:%M:%S")) %>%
  ggplot(aes(x= day, y = submission)) + 
  geom_point() + 
  scale_y_datetime(
    date_labels = "%H:%M", 
    limits = c(as.POSIXct("00:00:01", format="%H:%M:%S"), 
               as.POSIXct("23:59:59", format="%H:%M:%S")))

可行解决方案

方法1:使用hms包处理时间类型

hms包专门用于存储无日期的时间数据,ggplot对该类型的支持更适配,不会引入日期相关的冗余刻度:

library(tidyverse)
library(hms)

submits %>%
  mutate(submission = as_hms(submission)) %>%
  ggplot(aes(x = day, y = submission)) +
  geom_point(size = 3) +
  labs(x = "间隔天数", y = "提交时间") +
  theme_minimal()

运行后Y轴会自动生成合理的24小时制时间刻度,无冗余标签。

方法2:转换为小数小时并自定义刻度

将时间转换为一天中的小数小时数值,再手动设置Y轴的刻度标签为24小时格式:

submits %>%
  mutate(
    submission = hms::as_hms(submission),
    hour_decimal = as.numeric(submission) / 3600  # 转换为小时单位的小数
  ) %>%
  ggplot(aes(x = day, y = hour_decimal)) +
  geom_point(size = 3) +
  scale_y_continuous(
    breaks = seq(0, 24, 3),  # 每3小时一个刻度
    labels = function(x) sprintf("%02d:00", as.integer(x))
  ) +
  labs(x = "间隔天数", y = "提交时间") +
  theme_minimal()

这种方式可以灵活调整刻度间隔和标签样式。

方法3:统一POSIXct的基准日期

如果坚持使用POSIXct类型,需给所有时间指定同一个基准日期,避免因日期差异导致的刻度异常:

base_date <- as.POSIXct("2020-01-01")  # 任意固定基准日期

submits %>%
  mutate(
    submission = base_date + hms::as_hms(submission)
  ) %>%
  ggplot(aes(x = day, y = submission)) +
  geom_point(size = 3) +
  scale_y_datetime(
    date_labels = "%H:%M",
    breaks = seq(base_date, base_date + 24*3600, 3*3600),
    limits = c(base_date, base_date + 24*3600 - 1)
  ) +
  labs(x = "间隔天数", y = "提交时间") +
  theme_minimal()

通过固定基准日期,所有时间都落在同一天内,Y轴只会显示当天的24小时刻度,不会出现冗余标签。

内容的提问来源于stack exchange,提问作者medium-dimensional

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:20:45