双 x 轴(类似于 doubleYScale),带有额外或类似的格子
Double x axis (analog to doubleYScale) with lattice extra or similar
我想制作我们在海洋学中需要的具体数字。不幸的是,双轴、三轴或更多轴在 R 中的实现不是很好。我不需要像 doubleYScale of lattice extra 那样的双 y 轴。我需要双或三 x 轴。我找不到一种方法来使用 doubleYScale 来发挥我的优势。也许这是可能的。帮助将不胜感激。
这是我现在根据数据得出的:
Whosebug_fluo.csv: http://pastebin.com/embed_js.php?i=7KNEiytF
animals_Whosebug.csv:http://pastebin.com/embed_js.php?i=CnEJaq6b
重要更新:我忘了提到两个数据集的 y 轴上的深度值间隔不同。
library(latticeExtra)
#dataset 1
data1011 <- file.path('Whosebug_fluo.csv')
jdatax1 = read.csv(data1011)
jdatax1$stat<-as.factor(jdatax1$Station)
#dataset2
data1012 <- file.path('animals_Whosebug.csv')
jdatax2 = read.csv(data1012)
jdatax2$stat<-as.factor(jdatax2$stat)
#attempt multi axes
animals<-barchart( depth_good ~Mass | stat, data = jdatax2)
fluo<-xyplot( depth~chl | stat, data = jdatax1, type = "l")
doubleYScale(animals, fluo)
#plot
jpeg("double_y", width = 11, height = 8.5, units = 'in', res = 300)
doubleYScale(animals, fluo)
dev.off()
除了粉红色数据 (fluo) 需要它自己的轴外,我需要的完全一样。条形图必须是这样的,但实际上我想反转 y 轴,以便 0 位于顶部。实际数据也有更多的站点,所以大概是8块数据。
期待看看能用它做什么!
非常感谢!
编辑:
添加示例。看这里:
PS。我并不是说我想要看起来像那样的东西-.- 或有太多轴的东西。但是两个 x 会很好 -.-
据我所知,这里没有针对更一般问题的预打包解决方案。
下面的示例介绍了添加附加轴的几种方法。第二种方法也是更通用的方法(即使在沿绘图边界添加轴时我也倾向于使用它)的工作原理是先推动视口,然后沿其边缘添加轴。通过将视口推高一英寸(例如),它允许您生成一个浮动在绘图上方一英寸的轴。使用提供的 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"
)将绘制我们想要的基线。
我想制作我们在海洋学中需要的具体数字。不幸的是,双轴、三轴或更多轴在 R 中的实现不是很好。我不需要像 doubleYScale of lattice extra 那样的双 y 轴。我需要双或三 x 轴。我找不到一种方法来使用 doubleYScale 来发挥我的优势。也许这是可能的。帮助将不胜感激。
这是我现在根据数据得出的:
Whosebug_fluo.csv: http://pastebin.com/embed_js.php?i=7KNEiytF
animals_Whosebug.csv:http://pastebin.com/embed_js.php?i=CnEJaq6b
重要更新:我忘了提到两个数据集的 y 轴上的深度值间隔不同。
library(latticeExtra)
#dataset 1
data1011 <- file.path('Whosebug_fluo.csv')
jdatax1 = read.csv(data1011)
jdatax1$stat<-as.factor(jdatax1$Station)
#dataset2
data1012 <- file.path('animals_Whosebug.csv')
jdatax2 = read.csv(data1012)
jdatax2$stat<-as.factor(jdatax2$stat)
#attempt multi axes
animals<-barchart( depth_good ~Mass | stat, data = jdatax2)
fluo<-xyplot( depth~chl | stat, data = jdatax1, type = "l")
doubleYScale(animals, fluo)
#plot
jpeg("double_y", width = 11, height = 8.5, units = 'in', res = 300)
doubleYScale(animals, fluo)
dev.off()
除了粉红色数据 (fluo) 需要它自己的轴外,我需要的完全一样。条形图必须是这样的,但实际上我想反转 y 轴,以便 0 位于顶部。实际数据也有更多的站点,所以大概是8块数据。
期待看看能用它做什么! 非常感谢!
编辑: 添加示例。看这里:
据我所知,这里没有针对更一般问题的预打包解决方案。
下面的示例介绍了添加附加轴的几种方法。第二种方法也是更通用的方法(即使在沿绘图边界添加轴时我也倾向于使用它)的工作原理是先推动视口,然后沿其边缘添加轴。通过将视口推高一英寸(例如),它允许您生成一个浮动在绘图上方一英寸的轴。使用提供的 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"
)将绘制我们想要的基线。