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.