On Sat, Apr 2, 2011 at 1:29 AM, <Boris.Vasiliev at forces.gc.ca> wrote:
On Fri, Mar 11, 2011 at 12:28 AM,
<Boris.Vasiliev at forces.gc.ca> wrote:
Good afternoon,
I am trying to create a plot where the bottom and top
axes have the
same scale but different tick marks. ?I tried user-defined
xscale.component function but it does not produce
desired results.
Can anybody suggest where my use of xscale.component function is
incorrect?
For example, the code below tries to create a plot where
horizontal
axes limits are c(0,10), top axis has ticks at odd integers, and
bottom axis has ticks at even integers.
library(lattice)
df <- data.frame(x=1:10,y=1:10)
xscale.components.A <- function(...,user.value=NULL) {
?# get default axes definition list; print user.value
?ans <- xscale.components.default(...)
?print(user.value)
?# start with the same definition of bottom and top axes
?ans$top <- ans$bottom
?# - bottom labels
?ans$bottom$labels$at <- seq(0,10,by=2)
?ans$bottom$labels$labels <- paste("B",seq(0,10,by=2),sep="-")
?# - top labels
?ans$top$labels$at <- seq(1,9,by=2)
?ans$top$labels$labels <- paste("T",seq(1,9,by=2),sep="-")
?# return axes definition list
?return(ans)
}
oltc <- xyplot(y~x,data=df,
scales=list(x=list(limits=c(0,10),at=0:10,alternating=3)),
? ? ? ? ? ? ? xscale.components=xscale.components.A,
? ? ? ? ? ? ? user.value=1)
print(oltc)
The code generates a figure with incorrectly placed
bottom and top
labels. ?Bottom labels "B-0", "B-2", ... are at 0, 1, ...
and top labels "T-1", "T-3", ... are at 0, 1, ... ?When
axis-function runs out of labels, it replaces labels with NA.
It appears that lattice uses top$ticks$at to place labels and
top$labels$labels for labels. ?Is there a way to override this
behaviour (other than to expand the "labels$labels" vector to
be as long as "ticks$at" vector and set necessary elements to "")?
Well, <top|bottom>$ticks$at is used to place the ticks, and
$labels$at is used to place the labels. They should
typically be the
same, but you have changed one and not the other.
Everything seems to work if you set $ticks$at to the same
values as $labels$at:
? ? ## ?- bottom labels
+ ? ans$bottom$ticks$at <- seq(0,10,by=2)
? ? ans$bottom$labels$at <- seq(0,10,by=2)
? ? ans$bottom$labels$labels <- paste("B",seq(0,10,by=2),sep="-")
? ? ## ?- top labels
+ ? ans$top$ticks$at <- seq(1,9,by=2)
? ? ans$top$labels$at <- seq(1,9,by=2)
? ? ans$top$labels$labels <- paste("T",seq(1,9,by=2),sep="-")
Also, can user-parameter be passed into xscale.components()
function? (For example, locations and labels of ticks on the top
axis). ?In the ?code above, print(user.value) returns NULL even
though in the xyplot() call user.value is 1.
No. Unrecognized arguments are passed to the panel function only, not
to any other function. However, you can always define an inline
function:
oltc <- xyplot(y~x,data=df,
? ? ? ? ? ? ? ?scales=list(x=list(limits=c(0,10), at = 0:10,
? ? ? ? ? ? ? ? ? ? ? ? ? ?alternating=3)),
? ? ? ? ? ? ? ?xscale.components = function(...)
? ? ? ? ? ? ? ? ? ? ? ? ? ?xscale.components.A(..., user.value=1))
Hope that helps (and sorry for the late reply).
-Deepayan
Deepyan,
Thank you very much for your reply. ?It makes things a bit clearer.
It other words in the list prepared by xscale.components(), vectors
<top|bottom>$ticks$at and <top|bottom>$labels$at must be the same.
If only every second tick is to be labelled then every second label
should be set explicitly to empty strings:
Now when you put it that way, the current behaviour does seem
wrong (I didn't read your original post carefully enough). I
guess this was one of the not-yet-implemented things
mentioned in the Details section of ?xscale.components.default.
I have added support for different ticks$at and labels$at in
the SVN sources in r-forge. You can test it from there (your
original code works as expected). I won't make a new release
on CRAN until after R
2.13 is released (we are almost in code freeze now).
-Deepayan