ggplot的时间轴

时间:2019-05-08 13:35:14

标签: r ggplot2

我有一个时间序列(每小时)数据,我想打印该数据的选定时间段。假设我想从2019年1月1日00:00到2019年1月8日00:00打印一周的数据。我希望刻度线从2019年1月1日的00:00开始。但是出于我不知道的原因,ggplot从03:00开始。我想念什么吗?

以下是用于复制问题的示例代码:

library(ggplot2)
library(scales)
Sys.setenv( TZ = "GMT" )

datetime <- seq(from = as.POSIXct("2019-01-01", tz = "GMT"), length.out = 744, by = "hours")
random<- rnorm(744,100,20)

df <- data.frame(datetime,random)

time.start=as.POSIXct("2019-01-01 00:00",format="%Y-%m-%d %H:%M")
time.end=as.POSIXct("2019-01-08 00:00",format="%Y-%m-%d %H:%M")

png(filename = "test_ggplot.png", width = 800, height = 600, units = "px", pointsize = 24 )
plot.random = ggplot() + 
 geom_line(data=df, aes(x=datetime, y=random)) + 
 scale_x_datetime(limits = c(time.start,time.end),
          breaks = date_breaks("12 hours"),
          labels = date_format("%H:%M\n%d-%b")
          )
plot.random

以下是图形,其中显示了x轴刻度标记标签从03:00而不是00:00开始。

example ggplot time axis problem

2 个答案:

答案 0 :(得分:1)

我希望您的限制输入起作用,这可能是一个错误。如果我放弃limits参数并添加expand,它似乎可以满足您的要求:

ggplot() +
  geom_line(data = df %>% head(300), aes(x = datetime, y = random)) +
  scale_x_datetime(
    #limits = c(time.start, time.end),
    breaks = date_breaks("12 hours"),
    labels = date_format("%H:%M %d-%b"),
    expand = expand_scale(0)
  ) +
  theme(axis.text = element_text(angle = 90))

enter image description here

答案 1 :(得分:1)

轴标签的计算发生在ggplot2:::ggplot_build.ggplot内,这是绘制/打印ggplot对象时绘图构建过程的一部分。

如果我们深入研究底层代码(这可以在调试模式下完成,方法是从ggplot2:::ggplot_build.ggplotlayout$setup_panel_paramsself$coord$setup_panel_params进入兔子洞),我们可以看到< strong>轴标签/中断是基于轴限制 ,该限制已考虑到任何扩展。

此轴限制计算是通过ggplot2软件包的以下(未导出)函数完成的:

> ggplot2:::scale_range
function (scale, limits = NULL, expand = TRUE) 
{
    expansion <- if (expand) 
        expand_default(scale)
    else c(0, 0)
    if (is.null(limits)) {
        scale$dimension(expansion)
    }
    else {
        range <- range(scale$transform(limits))
        expand_range(range, expansion[1], expansion[2])
    }
}

在此处,将扩展量添加到代码中指定为c(time.start, time.end)的比例限制中。实际的扩展量取决于以下参数:

情况1:如果expand为真

扩展量取决于与比例相关的默认扩展,如ggplot2:::expand_default中所述:

  1. 如果指定了标度的扩展因子,则扩展量采用该值的向量;
  2. 否则,对于离散比例,扩展量采用默认的c(0, 0.6, 0, 0.6),对于连续比例,扩展量采用c(0.05, 0, 0.05, 0)

情况2:如果expand为假

扩展量被硬编码为c(0, 0)

因此,要保留用于轴折断/标签计算的比例尺限制c(time.start, time.end),必须满足以下两个条件之一:

  1. 标度的扩展因子指定为c(0, 0)(根据@ yake84的回答);
  2. expand的输入值为FALSE-这是从绘图对象的坐标系中的expand参数(默认为coord_cartesian)中获取的。

总而言之,以下任何一项都会为您提供相同的x轴标签:

p <- ggplot() + 
  geom_line(data = df, aes(x = datetime, y = random)) +
  # increase margin on the right to accommodate axis label right at the end
  theme(plot.margin = unit(c(5.5, 20, 5.5, 5.5), "pt")) 

# specify 0 expansion factor in scale
p +
  scale_x_datetime(limits = c(time.start, time.end),
                   breaks = date_breaks("12 hours"),
                   labels = date_format("%H:%M\n%d-%b"),
                   expand = c(0, 0))

# specify no expansion in coord (note this affects y-axis too)
p +
  scale_x_datetime(limits = c(time.start, time.end),
                   breaks = date_breaks("12 hours"),
                   labels = date_format("%H:%M\n%d-%b")) +
  coord_cartesian(expand = FALSE)

plot comparisons