R Plot指定时间刻度的数量 - 时间/日期相当于漂亮

时间:2011-07-06 06:57:15

标签: r plot

我想知道如何在x轴上绘制时间时可以绘制更多刻度线。

基本上,相当于漂亮的时间。显然,随着时间的推移不能很好地工作,因为它使用1,2,5和10的因子。对于时间,人们可能想要例如小时,半小时......

plot(as.POSIXct(x,origin="1960-01-01"),y,type="l",xlab="Time")

给出了太少且间隔很大的标记。

zoox<-zoo(y,as.POSIXct(stats$Time,origin="1960-01-01"))
plot(zoox)

给出相同的。

由于

编辑:

只是为了澄清(到目前为止答案没有解决我的问题):我正在寻找的是一个像日期一样漂亮的功能,例如:一个函数,它取一个开始日期,结束日期,一些刻度,并输出刻度的位置。也就是说,我很清楚可以绘制小时数,绘制分钟数以及其他内容,但是相当于自动化数字的刻度距离,日期的结果函数应该自行决定是否使用天,小时,分钟,秒,毫秒,微秒,30分钟,500微秒,5秒等间隔。无论如何,这就是为数字所做的事情。

EDIT2:

这是我目前用来决定时间轴格式的函数(注意这对日期不起作用):

mydiff <- end-start
if(mydiff>1800) {
    axis.POSIXct(1,xrange,format="%H:%M")
} else if(mydiff>30) {
    axis.POSIXct(1,xrange,format="%H:%M:%S")
} else if(mydiff>0.5) {
    axis.POSIXct(1,xrange,format="%H:%M:%OS3")
} else
    axis.POSIXct(1,xrange,format="%H:%M:%OS6")
}

我没有增加刻度线的功能,因此我使用默认的刻度线数

4 个答案:

答案 0 :(得分:9)

使用可重现的例子

set.seed(1)
x <- as.POSIXct(sort(sample(100000, 100)), origin="1960-01-01")
y <- rpois(100, 5)
plot(x, y, type = "l", xlab = "Time")

我们可以使用axis.POSIXct()函数(也可以使用Axis() S3泛型)向绘图添加自定义轴。这里的主要观点是,您(用户)完全可以控制抽签的位置以及标签的标注方式,如果默认值不合适,您只需要更加努力工作;这对您有用。

首先我们绘制数据但是禁止绘制x轴:

plot(x, y, type = "l", xlab = "Time", xaxt = "n")

接下来,我将在每小时开始时添加一个主刻度标记。为此我创建了一系列日期时间

  1. 来自系列中第一次观察的四舍五入小时,
  2. 进行观察的最后一小时结束(使用ceiling()将我们移至下一个小时),
  3. 以1小时(by = "1 hour")为单位递增序列。
  4. 此序列提供给at的{​​{1}}参数。如果没有阅读axis.POSIXct()?axis.POSIXct

    ,其他内容应该很容易理解
    ?par

    结果图如下:

    enter image description here

    为了显示更精细的控制,我现在在每个半小时位置添加次要刻度线,但是抑制这些刻度的注释(通过## add axis tick at each hour: axis.POSIXct(side = 1, x = x, at = seq(from = round(x[1], "hours"), to = x[1] + ceiling(difftime(tail(x, 1), head(x, 1), units = "hours")), by = "1 hour"), las = 2) 参数)并且还使次要刻度更短(通过图形参数{ {1}})。请注意labels方法的tcl参数如何获取所述间隔的数值

    seq()

    情节现在看起来像这样:

    enter image description here

    您可以添加自己的标签,而不是by功能提供的标签。如果你想这样做,那么我们应该将## add minor ticks at 30 min intervals to above plot axis.POSIXct(side = 1, x = x, at = seq(from = round(x[1], "hours"), to = x[1] + ceiling(difftime(tail(x, 1), head(x, 1), units = "hours")), by = "30 mins"), las = 2, tcl = -0.2, labels = FALSE) 的输出分配给一个对象,然后我们可以使用axis.POSIXct函数。例如:

    seq()

    结果图如下所示:

    enter image description here

    format()返回格式化日期时间的字符串。您可以plot(x, y, type = "l", xlab = "Time", xaxt = "n") tseq <- seq(from = round(x[1], "hours"), to = x[1] + ceiling(difftime(tail(x, 1), head(x, 1), units = "hours")), by = "1 hour") axis.POSIXct(side = 1, x = x, at = tseq, labels = format(tseq, format = "%H:%M"), las = 2) 关于您想要的任何其他内容,或查看可用于格式化format()中的日期时间对象的其他占位符

答案 1 :(得分:7)

axis.POSIXct()已经非常难以猜测轴的合适值,所以我首先要进行黑客攻击。目前,它依赖于使用pretty()应用于日期时间的某些功能。它使用pretty()的默认值,因此您可以破解该函数以添加nmin.n参数,这将增加所选择的漂亮标记的数量。

axis.POSIXct()复制到您自己的函数/文件中(给它一个新名称)。在定义中添加nmin.n参数,默认值可能大于pretty()函数使用的值。并将其传递给所有pretty()次调用。

试一试。如果它运行得相当好,那么你可以fixInNamespace(axis.POSIXct)对实际函数进行相同的更改,以便在所有调用它的图上使用它。

P.S。这是一个可能的黑客

function (side, x, at, format, labels = TRUE, n = 5, ...) {
  mat <- missing(at) || is.null(at)
  if (!mat) 
    x <- as.POSIXct(at)
  else x <- as.POSIXct(x)
  range <- par("usr")[if (side%%2) 
    1L:2L
    else 3L:4L]
  d <- range[2L] - range[1L]
  z <- c(range, x[is.finite(x)])
  attr(z, "tzone") <- attr(x, "tzone")
  if (d < 1.1 ) {
    sc <- 0.001
    if (missing(format)) 
      format <- "%H:%M:%OS6"
  }
  else if (d < 1.1 * 30) {
    sc <- 1
    if (missing(format)) 
      format <- "%H:%M:%OS3"
  }
  else if (d < 1.1 * 60) {
    sc <- 1
    if (missing(format)) 
      format <- "%H:%M:%S"
  }
  else if (d < 1.1 * 30 * 60) {
    sc <- 60
    if (missing(format)) 
      format <- "%H:%M:%S"
  }
  else if (d < 1.1 * 60 * 60) {
    sc <- 60
    if (missing(format)) 
      format <- "%H:%M"
  }
  else if (d < 1.3 * 60 * 60 * 24) {
    sc <- 60 * 60
    if (missing(format)) 
      format <- "%H:%M"
  }
  else if (d < 2 * 60 * 60 * 24) {
    sc <- 60 * 60
    if (missing(format)) 
      format <- "%a %H:%M"
  }
  else if (d < 7 * 60 * 60 * 24) {
    sc <- 60 * 60 * 24
    if (missing(format)) 
      format <- "%a"
  }
  else {
    sc <- 60 * 60 * 24
  }
  if (d < 60 * 60 * 24 * 50) {
    zz <- pretty(z/sc,n=n)
    z <- zz * sc
    z <- .POSIXct(z, attr(x, "tzone"))
    if (sc == 60 * 60 * 24) 
      z <- as.POSIXct(round(z, "days"))
    if (missing(format)) 
      format <- "%b %d"
  }
  else if (d < 1.1 * 60 * 60 * 24 * 365) {
    z <- .POSIXct(z, attr(x, "tzone"))
    zz <- as.POSIXlt(z)
    zz$mday <- zz$wday <- zz$yday <- 1
    zz$isdst <- -1
    zz$hour <- zz$min <- zz$sec <- 0
    zz$mon <- pretty(zz$mon,n=n)
    m <- length(zz$mon)
    M <- 2 * m
    m <- rep.int(zz$year[1L], m)
    zz$year <- c(m, m + 1)
    zz <- lapply(zz, function(x) rep(x, length.out = M))
    zz <- .POSIXlt(zz, attr(x, "tzone"))
    z <- as.POSIXct(zz)
    if (missing(format)) 
      format <- "%b"
  }
  else {
    z <- .POSIXct(z, attr(x, "tzone"))
    zz <- as.POSIXlt(z)
    zz$mday <- zz$wday <- zz$yday <- 1
    zz$isdst <- -1
    zz$mon <- zz$hour <- zz$min <- zz$sec <- 0
    zz$year <- pretty(zz$year,n=n)
    M <- length(zz$year)
    zz <- lapply(zz, function(x) rep(x, length.out = M))
    z <- as.POSIXct(.POSIXlt(zz))
    if (missing(format)) 
      format <- "%Y"
  }
  if (!mat) 
    z <- x[is.finite(x)]
  keep <- z >= range[1L] & z <= range[2L]
  z <- z[keep]
  if (!is.logical(labels)) 
    labels <- labels[keep]
  else if (identical(labels, TRUE)) 
    labels <- format(z, format = format)
  else if (identical(labels, FALSE)) 
    labels <- rep("", length(z))
  axis(side, at = z, labels = labels, ...)
}

可以看到与原始函数的差异here

答案 2 :(得分:3)

我倾向于使用函数axis.POSIXct和/或函数cut.POSIXt。假设您的日期向量为time,并且您的值向量与x相关联:

plot(time,x,xaxt="n")
axis.POSIXct(side=1,at=seq(min(time),max(time),by="week"),format="%d-%m") #For instance

并且,进一步,cut.POSIXt

plot(time,x,xaxt="n")
axis.POSIXct(side=1,at=cut(time, breaks="week"),format="%d-%m")

答案 3 :(得分:0)

在图(axes = FALSE或单个轴)中抑制轴可用的默认值,并使用功能轴详细说明轴的所需内容(特别是at参数)。见?axis

plot(cars, axes = FALSE)
axis( 1, at = c(5,6,7,10,11,12,21,22,23) )