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

使用scales::label_time时X轴天数计数未从0开始的优化方案咨询

温度随时间变化绘图的X轴优化方案

我有一个用于跟踪温度随时间变化的表格d_raw,计划使用lubridate整理数据后进行绘图。但遇到X轴未从0开始计数的问题,目前通过labels = function(x) {paste(hms(x)/days(1))}临时解决,但该方法不够优雅,希望能得到改进脚本的建议。

原始代码与问题

library(tidyverse)

d_raw <- tibble(
  Time = c("2023-02-01 14:00", "2023-02-02 12:00", "2023-02-03 13:00", "2023-02-04 14:00", "2023-02-05 15:00"),
  Temperature = c(25,18,20,19,32)
)

Tzero <- ymd_hm("2023-02-01 8:00")

d <- d_raw |> 
  mutate(Time = ymd_hm(Time),
         spent = interval(Tzero, Time))

d
#> # A tibble: 5 × 3
#>   Time                Temperature spent                                            
#>   <dttm>                    <dbl> <Interval>                                       
#> 1 2023-02-01 14:00:00          25 2023-02-01 08:00:00 UTC--2023-02-01 14:00:00 UTC
#> 2 2023-02-02 12:00:00          18 2023-02-01 08:00:00 UTC--2023-02-02 12:00:00 UTC
#> 3 2023-02-03 13:00:00          20 2023-02-01 08:00:00 UTC--2023-02-03 13:00:00 UTC
#> 4 2023-02-04 14:00:00          19 2023-02-01 08:00:00 UTC--2023-02-04 14:00:00 UTC
#> 5 2023-02-05 15:00:00          32 2023-02-01 08:00:00 UTC--2023-02-05 15:00:00 UTC

尝试直接绘图时,用scale_x_time设置X轴从0开始,标签显示天数,但结果不符合预期:

p <- ggplot(d, aes(x = spent, y = Temperature)) +
  geom_point() +
  geom_line() +
  xlab("Time spent (d)") +
  ylim(c(0, NA))

p + scale_x_time(limits = c(0,NA),
               breaks = scales::breaks_width("2 days"),
               labels = scales::label_time("%d"))

初始绘图

临时解决方法虽然能显示正确的天数,但会出现解析警告,且代码不够简洁:

p + scale_x_time(limits = c(0,NA),
                 breaks = scales::breaks_width("2 days"),
                 labels =  function(x) {paste(hms(x)/days(1))})
#> Warning in .parse_hms(..., order = "HMS", quiet = quiet): Some strings failed
#> to parse, or all strings are NAs

临时解决后的绘图

改进方案

核心问题是用interval类型作为X轴变量不太适合数值化的时间差展示,直接计算从Tzero到每个时间点的**天数差(数值型)**会更直观,也能避免类型转换的问题。

步骤1:重新整理数据

将spent字段改为计算时间差的数值,用difftime转换为天数:

d <- d_raw |> 
  mutate(Time = ymd_hm(Time),
         # 直接计算与Tzero的天数差,保留小数精度
         spent_days = as.numeric(difftime(Time, Tzero, units = "days")))

整理后的数据:

d
#> # A tibble: 5 × 3
#>   Time                Temperature spent_days
#>   <dttm>                    <dbl>      <dbl>
#> 1 2023-02-01 14:00:00          25      0.25 
#> 2 2023-02-02 12:00:00          18      1.167
#> 3 2023-02-03 13:00:00          20      2.208
#> 4 2023-02-04 14:00:00          19      3.25 
#> 5 2023-02-05 15:00:00          32      4.292

步骤2:绘图优化

现在X轴是数值型,直接用scale_x_continuous设置刻度和标签,代码简洁无警告:

ggplot(d, aes(x = spent_days, y = Temperature)) +
  geom_point() +
  geom_line() +
  xlab("Time spent (d)") +
  ylim(c(0, NA)) +
  scale_x_continuous(
    limits = c(0, NA),
    breaks = scales::breaks_width(2), # 每2天设置一个刻度
    labels = scales::label_number(accuracy = 0.1) # 按需调整小数精度
  )

这样绘制的图X轴从0开始,天数显示准确,完全满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 02:07:24