Allen,

I can reproduce the problems you described, but I can't find where the
problem is (in axis.POSIXct). Anyway, here is an alternative I wrote a
while ago:

# for base graphics
timeAxis <- function(side, at=NULL, labels=TRUE, ..., tz="GMT") {
        range <- par("usr")[if (side%%2) 1:2 else 3:4]
        axisStuff <- timeAxisComponents(range, label=labels, tz=tz)
        labels <- axisStuff$label
        labels[labels == ""] <- NA
        axis(side, at=axisStuff$at, labels=labels, ...)
}

# for grid graphics
grid.xaxis.POSIXt <- function(lim=convertX(unit(0:1,"npc"), "native",
valueOnly=T),
        label=T, draw=T, name=NULL, ...)
{
        axisStuff <- timeAxisComponents(lim, label=label)
        if (label==F) axisStuff$label <- F
        tmp <- xaxisGrob(at=axisStuff$at, label=axisStuff$label, name=name, ...)
        if (label) tmp <- editGrob(tmp, gPath=gPath("labels"), check.overlap=F)
        if (draw) grid.draw(tmp)
        tmp
}

# lim should be POSIXct or numeric equivalent (i.e. secs since 1970)
timeAxisComponents <- function(lim, label=TRUE, tz="GMT") {
        stopifnot(length(lim) == 2)
        if (is.numeric(lim)) {
                class(lim) <- c("POSIXt", "POSIXct")
                attr(lim, "tzone") <- tz
        }
        timelim <- as.POSIXct(lim)
        lim <- as.numeric(timelim)
        startTime <- min(timelim)
        # utility functions for making pretty times
        truncMonth <- function(thisPOSIXt) {
                zz <- as.POSIXlt(thisPOSIXt)
                zz$mday <- 1
                zz$hour <- zz$min <- zz$sec <- 0
                zz$isdst <- -1
                zz
        }
        truncYear <- function(thisPOSIXt) {
                zz <- as.POSIXlt(thisPOSIXt)
                zz$mday <- 1
                zz$mon <- zz$hour <- zz$min <- zz$sec <- 0
                zz$isdst <- -1
                zz
        }
        truncDecade <- function(thisPOSIXt) {
                zz <- as.POSIXlt(truncYear(thisPOSIXt))
                zz$year <- (zz$year %/% 10) * 10
                zz
        }
        trunc.century <- function(thisPOSIXt) {
                zz <- as.POSIXlt(truncYear(thisPOSIXt))
                zz$year <- (zz$year %/% 100) * 100
                zz
        }
        # work out time sequence and formatting, depending on the time scale
        # each of tickSpec and labelSpec defines a time sequence and formatting
        tickSpec <- list(by="1 hour", format="%m-%d %H:%M",
                from=trunc(startTime, units="hours"))
        labelSpec <- tickSpec
        if (diff(range(lim)) > 8 * 60*60) { # 8 hours
                labelSpec$by <- "3 hours"
                labelSpec$from <- trunc(startTime, units="days")
        }
        if (diff(range(lim)) > 24 * 60*60) { # 24 hours
                tickSpec <- labelSpec
                labelSpec$by <- "12 hours"
        }
        if (diff(range(lim)) > 2 * 24*60*60) { # 2 days
                tickSpec <- labelSpec
                labelSpec$by <- "1 DSTday"
                labelSpec$format <- "%Y-%m-%d"
        }
        if (diff(range(lim)) > 3 * 24*60*60) { # 3 days
                # only put ticks at day labels (no sub-ticks)
                tickSpec <- labelSpec
        }
        if (diff(range(lim)) > 7 * 24*60*60) { # 7 days
                tickSpec <- labelSpec
                labelSpec$by <- "3 DSTdays"
                # ignore up to 3 days of previous month to find start date
                labelSpec$from <- truncMonth(startTime + 4*24*60*60)
        }
        if (diff(range(lim)) > 18 * 24*60*60) { # 18 days
                labelSpec$by <- "7 DSTdays"
                # ignore up to 7 days of previous month to find start date
                labelSpec$from <- truncMonth(startTime + 7*24*60*60)
                # leave ticks going by 1 day
        }
        if (diff(range(lim)) > 1.1 * 30*24*60*60) { # 1 month
                labelSpec$by <- "1 month"
                # leave ticks going by 1 day
        }
        if (diff(range(lim)) > 1.85 * 30*24*60*60) { # 2 months
                labelSpec$format <- "%Y-%m"
                # only put ticks at month labels (no sub-ticks)
                tickSpec <- labelSpec
        }
        if (diff(range(lim)) > 6 * 30*24*60*60) { # 6 months
                tickSpec <- labelSpec
                labelSpec$by <- "3 months"
                labelSpec$format <- "%Y-%b"
                labelSpec$from <- truncYear(startTime)
        }
        if (diff(range(lim)) > 2 * 365.25*24*60*60) { # 2 years
                tickSpec <- labelSpec
                labelSpec$by <- "1 year"
                labelSpec$format <- "%Y"
        }
        if (diff(range(lim)) > 3.5 * 365.25*24*60*60) { # 3.5 years
                # only put ticks at year labels (no sub-ticks)
                tickSpec <- labelSpec
        }
        if (diff(range(lim)) > 8 * 365.25*24*60*60) { # 8 years
                tickSpec <- labelSpec
                labelSpec$by <- "2 years"
                labelSpec$from <- truncDecade(startTime)
        }
        if (diff(range(lim)) > 12 * 365.25*24*60*60) { # 12 years
                labelSpec$by <- "5 years"
                # leave ticks going by 1 year
        }
        if (diff(range(lim)) > 30 * 365.25*24*60*60) { # 30 years
                tickSpec <- labelSpec
                labelSpec$by <- "10 years"
        }
        if (diff(range(lim)) > 60 * 365.25*24*60*60) { # 60 years
                # drop 5-year ticks
                tickSpec <- labelSpec
        }
        if (diff(range(lim)) > 100 * 365.25*24*60*60) { # 100 years
                labelSpec$by <- "20 years"
                labelSpec$from <- trunc.century(startTime)
        }
        # make sequence of axis ticks
        at <- seq(tickSpec$from, max(timelim), by=tickSpec$by)
        at <- at[(min(timelim) <= at) & (at <= max(timelim))]
        # blank labels
        atLabels <- rep("", length(at))
        if (label) {
                labelAt <- seq(labelSpec$from, max(timelim), by=labelSpec$by)
                labelIdx <- c(na.omit(match(as.numeric(labelAt), 
as.numeric(at))))
                atLabels[labelIdx] <- format(at[labelIdx], labelSpec$format)
        }
        return(list(at=at, label=atLabels))
}



On 10/26/07, Allen McIntosh <[EMAIL PROTECTED]> wrote:
> I recently called plot(x,y) where x was an array of POSIXct timestamps,
> and was pleasantly surprised that it produced a nice plot right out of
> the box:
>
> z <- as.POSIXct(c("2006-10-26 08:00:00 EDT","2007-10-25 12:00:00 EDT"))
> x <- seq(z[1],z[2],len=100)
> y <- 1:100
> plot(x,y,type="l")
>
> The X axis had nice labels, one tick mark every other month.  (Plotting
> on a 1024x768 X11 display, Fedora Core 5, R version 2.5.1.)
>
> What I really wanted to do was a little more elaborate, involving
> multiple Y variables, so I did the following to draw the axes and frame
> the plot:
>
> plot(range(x),range(y),type="n")
>
> and suddenly the nice X axis labels were not so nice anymore.  There
> were three tickmarks labeled "Nov", "Oct" and "Nov", and that's all.
>
> (range(x) strips the tzone attribute from x, but replacing range(x) with
> c(x[1],x[100]) doesn't change anything).
>
> If x covers a slightly larger span of time, e.g.
>
> z <- as.POSIXct(c("2006-10-1 08:00:00 EDT","2007-10-25 12:00:00 EDT"))
> x <- seq(z[1],z[2],len=100)
> plot(x,y,type="l")
>
> then the x axis labeling is also problematic, consisting of a single
> tick at "2007".
>
> Is there anything I can do about this, short of turning off automatic X
> labels and doing things myself?
>
> ______________________________________________
> R-help@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>


-- 
Felix Andrews / 安福立
PhD candidate
Integrated Catchment Assessment and Management Centre
The Fenner School of Environment and Society
The Australian National University (Building 48A), ACT 0200
Beijing Bag, Locked Bag 40, Kingston ACT 2604
http://www.neurofractal.org/felix/
3358 543D AAC6 22C2 D336  80D9 360B 72DD 3E4C F5D8

______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to