據我所知,這裏沒有預先包裝的解決方案來解決更一般的問題。
下面的示例介紹了幾種添加附加軸的方法。第二種和更一般的方法(即使在沿着繪圖邊界添加軸時我傾向於使用該方法)通過首先推動視口並沿着其邊緣添加軸來工作。通過將視口推入一英寸高度(例如),它可以讓您生成一個在圖上浮動一英寸的軸。使用提供的參數xlim=
參數推送視口還允許您設置其本地座標系,該座標系允許您避開一些其他需要的座標系轉換。
下面這些中等評論的代碼還有很多,我會讓你自己去探索一下!
library(lattice)
library(grid)
## Functions for converting units between axes
year2salinity <- function(year) {33 + (1/30)*(year-1900)}
salinity2year <- function(salinity) 1900 + 30*(salinity-33)
year2copepod <- function(year) {1000 + 100*(year-1900)}
## A better pretty(). (base::pretty() will often return limits that
## run beyond plot's ends.)
prettyBetween <- function(x,...) {
xx <- pretty(x,...)
xx[xx >= min(x) & xx <= max(x)]
}
## Custom axis-drawing function to be invoked via xyplot(..., axis=customAxis)
customAxis <- function(side, ...) {
if (side == "top") {
xlim <- current.panel.limits()$xlim
## Method #1 (Only works for axis along side of plot)
atSalinity <- prettyBetween(year2salinity(xlim))
panel.axis(side = side, outside = TRUE, at=salinity2year(atSalinity),
labels = as.character(atSalinity),
rot=0)
grid.text("Salinity", gp=gpar(cex=0.9),
y=unit(1, "npc") + unit(2.5, "lines"))
## Method #2 (Works for "floating" axis or -- with viewport height=0 --
## for axis along side of plot.)
atCopepod <- prettyBetween(year2copepod(xlim))
pushViewport(viewport(height = unit(4, "lines"),
y = 1, just = "bottom",
xscale = year2copepod(xlim)))
panel.axis(side = side, outside = TRUE, at=atCopepod,
labels = as.character(atCopepod),
line.col = "grey65", text.col = "grey35", rot=0)
## panel.axis doesn't draw the axis' "baseline", so we do it using grid.axis
grid.xaxis(at = atCopepod, label = FALSE,
main = FALSE, gp = gpar(col="grey65"))
grid.text(expression("Copepods m"^{-3}), gp=gpar(cex=0.9, col="grey35"),
y=unit(1, "npc") + unit(2.5, "lines"))
popViewport()
}
else {
axis.default(side = side, ...)
}
}
xyplot(nhtemp ~ time(nhtemp), aspect = "xy", type = "o",
xlab = "Year", ylab = "Temperature",
axis = customAxis,
main = "Yearly temperature, salinity, and copepod abundance",
scales = list(x=list(alternating=3)),
## Set up key.axis.padding (an element of each lattice plot's layout) to
## understand values in terms of lines...
lattice.options=list(layout.heights=list(key.axis.padding=list(x=1,units="lines"))),
## ... so that you can tell it you need 6 "lines" of space for axes
par.settings = list(layout.heights=list(key.axis.padding=6)))
補充說明,主要是爲我自己:
上面的代碼需要既panel.axis()
和grid.xaxis()
調用,這是不甚理想。我們需要調用grid.xaxis()
(並且就此而言定義函數prettyBetween()
)的唯一原因是panel.axis()
繪製刻度線和標籤,但不繪製軸基線。如果panel.axis()
有選擇這樣做,這裏的事情會更簡單。要了解這將是一樣,運行trace()
到一些額外的基線繪製代碼附加到每個panel.axis()
電話...
trace(panel.axis,
exit=expression(
grid.lines(x = unit(at[c(1,length(at))], "native"),
y = unit(c(1,1), "npc"),
gp = gp.line)))
....之後調用面板軸(帶side=="top"
)將繪製我們想要的基線。
您是否可以包含指向您要查找的類型圖的鏈接? (我會特別感興趣的是看到一個三軸x軸。) –
非常感謝。好點子。我添加了一個例子。往上看! –