From gavin.simpson at ucl.ac.uk  Thu Jun  2 13:45:09 2005
From: gavin.simpson at ucl.ac.uk (gavin.simpson@ucl.ac.uk)
Date: Thu Jun  2 13:45:17 2005
Subject: [Rd] Wishlist: more flexible handling of tick labels in axis.Date
	(PR#7913)
Message-ID: <20050602114509.C34C28709@slim.kubism.ku.dk>

Full_Name: Gavin Simpson
Version: 2.1.0-patched (1-Jun-2005)
OS: Linux (Fedora Core 3)
Submission from: (NULL) (128.40.32.76)


axis.Date() insists on labelling tick marks. It could be made more flexible by
allowing the user to specify if they want the ticks to be labelled, for example,
to add un-labelled minor ticks for "months", added to a plot with "years"
labelled. The user can not define labels = "" in the "..." in the call to
axis.Date() as axis.Date() calls axis() with labels = labels explicitly,
resulting in:

Error in axis(side, at = z, labels = labels, ...) : 
	formal argument "labels" matched by multiple actual arguments

if you try.

One way round this would be to add labels as a named argument to axis.Date() and
to allow labels to be NULL (missing), TRUE or FALSE. A first attempt at this is
shown below:

axis.Date2 <- function (side, x, at, format, labels, ...)
{
    mat <- missing(at)
    if (!mat)
        x <- as.Date(at)
    else x <- as.Date(x)
    range <- par("usr")[if (side%%2)
        1:2
    else 3:4]
    range[1] <- ceiling(range[1])
    range[2] <- floor(range[2])
    d <- range[2] - range[1]
    z <- c(range, x[is.finite(x)])
    class(z) <- "Date"
    if (d < 7)
        if (missing(format))
            format <- "%a"
    if (d < 100) {
        z <- structure(pretty(z), class = "Date")
        if (missing(format))
            format <- "%b %d"
    }
    else if (d < 1.1 * 365) {
        zz <- as.POSIXlt(z)
        zz$mday <- 1
        zz$mon <- pretty(zz$mon)
        m <- length(zz$mon)
        m <- rep.int(zz$year[1], m)
        zz$year <- c(m, m + 1)
        z <- .Internal(POSIXlt2Date(zz))
        if (missing(format))
            format <- "%b"
    }
    else {
        zz <- as.POSIXlt(z)
        zz$mday <- 1
        zz$mon <- 0
        zz$year <- pretty(zz$year)
        z <- .Internal(POSIXlt2Date(zz))
        if (missing(format))
            format <- "%Y"
    }
    if (!mat)
        z <- x[is.finite(x)]
    z <- z[z >= range[1] & z <= range[2]]
    z <- sort(unique(z))
    # if labels is missing or TRUE generate labels for ticks
    if (missing(labels) || labels == TRUE)
      labels <- format.Date(z, format = format)
    # else rep "" to suppress labelling
    else labels <- rep("", length(z))
    axis(side, at = z, labels = labels, ...)
}

An example of using this with the Date example from ?plot.Date :

random.dates <- as.Date("2001/1/1") + 70*sort(runif(100))
plot(random.dates, 1:100, xaxt="n")
axis.Date2(1, at=seq(as.Date("2001/1/1"), max(random.dates)+6, "weeks"))
axis.Date2(1, at=seq(as.Date("2001/1/1"), max(random.dates)+6, "days"),
    labels = FALSE, tcl = -0.2)

The function should perhaps enforce NULL/TRUE/FALSE for labels, or could be
enhanced to allow labels = "" explicitly or to allow user defined vector for
labels that is of length(at).

Thanks,

Gavin


[Rd] Wishlist: more flexible handling of tick labels in axis.Date (PR#7913)
gavin.simpson@ucl.ac.uk