[R] [lattice] format and rotation of strip text
Tom Roche
Tom_Roche at pobox.com
Mon Nov 19 04:05:56 CET 2012
https://stat.ethz.ch/pipermail/r-help/2012-November/329479.html
>> Hopefully [sufficiently] "small, self-contained example":
mailquotes omitted from "start example" to "end example" to
ease rerunning the following code:
# start example
library(reshape2)
library(lattice)
lon=11
lat=7
lev=5
len=lon*lat*lev
array.3d <- array(data=c(1:len), dim=c(lat, lon, lev))
# Rewrite the array values "more spatially," i.e., row-wise from
# bottom left. If there's a more-R-ish way to fill this array as
# desired, please let me know: I know 'for' loops are deprecated
# in R.
i=1
for (z in 1:lev) {
for (x in lat:1) {
for (y in 1:lon) {
array.3d[x,y,z]=i ; i=i+1
}
}
}
# produces (with rows=latitudes and cols=longitudes)
array.3d[,,1]
array.3d[,,lev]
# convert data=array.3d to dataframe with reshape2::melt
array.3d.df <- melt(array.3d, varnames=c("lat","lon","lev"), value.name="conc")
head(array.3d.df)
tail(array.3d.df)
# make level values {longer, "more realistic"}
array.3d.df$lev <- array.3d.df$lev + 0.12345 # truncated below, and ...
# ... below note output from these
head(array.3d.df)
tail(array.3d.df)
# plot "appropriately" for atmospheric data where lev=pressure: use
# * lattice::levelplot
# * one column, since atmospheric levels stack vertically
# * rev(lev), since layers closer to ground level have higher pressure
levelplot(
conc ~ lon * lat | rev(lev), data=array.3d.df,
layout=c(1,lev), # show levels stacked in 1 vertical column
strip=FALSE, # this suppresses printing strips atop packets
strip.left=strip.custom(
strip.levels=TRUE, # print level values
strip.names=FALSE # don't print name of level variable="rev(lev)"
)
)
# end example
>> Note that the (colored) 'strip' for each panel in the lattice has
>> - the corresponding layer value printed inside curly brackets, e.g.,
>> '{1.12345}'
>> - the layer value printed in full
>> - the layer value rotated 90° CCW (like the y-axis label)
>> I would prefer to have
>> + the layer value *not* printed inside curly brackets
>> + the layer value *not* rotated 90° CCW (i.e., to print the layer
>> value like the x-axis label)
>> + the layer value truncated or rounded to some significant digits,
>> e.g., '1.1'
https://stat.ethz.ch/pipermail/r-help/2012-November/329505.html
> levelplot(
> conc ~ lon * lat | rev(lev), data=array.3d.df,
> layout=c(1,lev), levs=as.character(round(array.3d.df[['lev']], 1)),
> strip=FALSE,
> strip.left=strip.custom(
> factor.levels=as.character(round(array.3d.df[['lev']], 3)),
> strip.levels=TRUE,
> horizontal=TRUE,
> strip.names=FALSE ,
> par.strip.text=list( cex=0.5)
> )
> )
...
> Your example does not do a very good job of testing the levels
> assignments since they are all the same.
Actually, that claim is false, as can be demonstrated in 2 ways:
1. (simple) Note column=lev in output from
head(array.3d.df)
tail(array.3d.df)
The levels are not "all the same."
2. (more complex, but clearly demonstrates a flaw in the suggestion)
Shorten the level values, then comment out the 'factor.levels'
argument to strip.custom (above), and plot:
# shorten level values by 2 digits, for bug demonstration
array.3d.df$lev <- array.3d.df$lev - 0.00045
# note different output from these in column=lev
head(array.3d.df)
tail(array.3d.df)
# comment out for debugging
levelplot(
conc ~ lon * lat | rev(lev), data=array.3d.df, layout=c(1,lev),
levs=as.character(round(array.3d.df[['lev']], 1)),
strip=FALSE,
strip.left=strip.custom(
# factor.levels=as.character(round(array.3d.df[['lev']], 3)),
strip.levels=TRUE,
horizontal=TRUE,
strip.names=FALSE ,
par.strip.text=list(cex=0.5)
)
)
Note that,
- without the line above commented out, strip values are (correctly)
all 1.123
+ with the line above commented out, strip values are (correctly)
1.123 .. 5.123
Am I missing something? If not, how to round() or signif() the values
obtained from array.3d.df$lev and displayed in the strips?
Your assistance is appreciated, Tom Roche <Tom_Roche at pobox.com>
More information about the R-help
mailing list