双x轴(类似于双倍的双倍)与晶格额外或类似 [英] Double x axis (analog to doubleYScale) with lattice extra or similar

查看:233
本文介绍了双x轴(类似于双倍的双倍)与晶格额外或类似的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在海洋学方面提出我们需要的具体数字。不幸的是,双重,三重或更多的轴在R中并不是很好的实现。我不需要双倍的y轴,因为在双倍的晶格额外的情况下。我需要双轴或三轴x轴。我无法找到一种方法来使用双倍的比例来获得我的优势。也许这是可能的。帮助将不胜感激。



这就是我现在基于这些数据得到的结果:

stackoverflow_fluo.csv:



我需要的只是粉红色数据(fluo)需要它自己的轴。条形图必须是这样的,但实际上我想让y轴反转,使0位于顶部。实际的数据也有更多的电台,所以它会像8块数据。



期待看到可以做什么!
非常感谢!






编辑:
新增示例。看到这里:




PS。我并不是说我想要一些看起来像这样的东西 - 或者轴数太多。但是,两个x会很好.-

解决方案

据我所知,这里没有预先包装的解决方案。

下面的例子介绍了几种添加附加轴的方法。第二种和更一般的方法(即使在沿着绘图边界添加轴时我倾向于使用该方法)通过首先推动视口并沿着其边缘添加轴来工作。通过将视口推入一英寸高度(例如),它可以让您生成一个在图上浮动一英寸的轴。使用提供的 xlim = 参数来推送视口也允许您设置其本地坐标系,从而允许您避开一些其他需要的坐标系转换。



以下适度评论的代码还有很多,我会让你自己去探索一下!

  library(lattice)
library(grid)

##在轴之间转换单位的函数
year2salinity < - function(year){33 + (年)-1000 + 100 *年(年)-1900)(年)(年)1900年b $ b盐度2年< - 功能(盐度)1900 + 30 *(盐度-33) (1900年)}

##更漂亮()。 (base :: pretty()通常会返回限制,即
##超出了plot的结尾。)
prettyBetween< - function(x,...){
xx< - 漂亮(x,...)
xx [xx> = min(x)& xx <= max(x)]
}

##通过xyplot(...,axis = customAxis)调用的自定义轴绘图函数
customAxis< - function(side,...){
if(side ==top){
xlim< - current.panel.limits()$ xlim
##方法#1 (仅适用于绘图边上的轴)
atSalinity < - prettyBetween(year2salinity(xlim))
panel.axis(side = side,outside = TRUE,at = salinity2year(atSalinity),$ b (bs)= as.character(atSalinity),
rot = 0)
grid.text(Salinity,gp = gpar(cex = 0.9),
y = unit(1, npc)+ unit(2.5,lines))
##方法#2(适用于浮动轴或 - 视口高度= 0 -
## )
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不绘制轴''baseline',所以我们使用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 =年度温度,盐度和桡足类丰度 ,
scales = list(x = list(alternating = 3)),
##将key.axis.padding(每个格子图布局的一个元素)设置为
##以行的形式理解值...
lattice.options = list(layout.heights = list(key.axis.padding = list(x = 1,units =lines))),
## ...所以你可以告诉它你需要6个线 b $ b par.settings = list(layout.heights = list(key.axis.padding = 6)))






我自己:



上面的代码需要调用 panel.axis() grid.xaxis(),这并不是很理想。我们需要调用 grid.xaxis()(以及为此定义函数 prettyBetween())是 panel.axis()绘制刻度和标签,但不是轴基线。如果 panel.axis()有一个选项可以这样做,这里的事情会简单得多。要看看会发生什么,运行 trace()来为每个 panel.axis()附加一些额外的基线绘图代码。 code> call ...

  trace(panel.axis,
exit = expression($ b $ (c(1,length(at))],native),
y = unit(c(1,1),npc),
gp = gp.line)))

...之后调用面板轴(with side ==top)会绘制我们想要的基线。

I want to make specific figures that we need in oceanography. Unfortunately double, triple or more axes are not very good implemented in R. I don't need a double y axis as in doubleYScale of lattice extra. I need double or triple x axis. I could not find a way to use doubleYScale to my advantage. Maybe that's possible. Help would be appreciated a lot.

This is what I have now based on the data:

stackoverflow_fluo.csv: http://pastebin.com/embed_js.php?i=7KNEiytF

animals_stackoverflow.csv:http://pastebin.com/embed_js.php?i=CnEJaq6b

Important update: I forgot to mention that the depth values on the y-axis of both datasets are differently spaced.

library(latticeExtra)
#dataset 1

    data1011 <- file.path('stackoverflow_fluo.csv')
    jdatax1 = read.csv(data1011)
    jdatax1$stat<-as.factor(jdatax1$Station)

    #dataset2

    data1012 <- file.path('animals_stackoverflow.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()

What I need is exactly like that except that the pink data (fluo) needs it's own axis. The bar chart has to be like this but in fact I would like to have the y axis reversed so that 0 is at the top. The actual data has also more stations, so it would be like 8 panels of data.

Looking forward to see what can be done with this! Thanks a lot!


EDIT: Added example. See here:

PS. I am not saying that I want something looking like that-.- or with too many axes. But two x would be nice -.-

解决方案

As far as I know, there's no prepackaged solution to the more general question here.

The example below presents a couple of approaches to adding an additional axis. The second and more general approach (which I'd be inclined to use even when adding an axis along the plot's boundary) works by first pushing a viewport and then adding an axis along its edge. By pushing a viewport an inch high (for example) it allows you to produce an axis that floats an inch above the plot. Pushing a viewport with a supplied xlim= argument also allows you to set its native coordinate system, which allows you to sidestep some otherwise-required coordinate-system conversions.

There's much more in the moderately-commented code below, which I'll let you explore on your own!

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)))


Additional note, mostly for myself:

The code above requires calls to both panel.axis() and grid.xaxis(), which is not really ideal. The only reason we need to call grid.xaxis() (and, for that matter, to define the function prettyBetween()) is that panel.axis() draws ticks and labels but not the axis baseline. If panel.axis() had an option to do so, things here would be a lot simpler. To see what that would be like, run trace() to append a bit of extra baseline-drawing code to each panel.axis() call...

trace(panel.axis,
      exit=expression(
      grid.lines(x = unit(at[c(1,length(at))], "native"),
                    y = unit(c(1,1), "npc"),
                    gp = gp.line)))

.... after which calls to panel axis (with side=="top") will plot the baseline we'd like.

这篇关于双x轴(类似于双倍的双倍)与晶格额外或类似的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆