2015-11-07 4 views
2

Я хочу сделать конкретные цифры, которые нам нужны в океанографии. К сожалению, двойные, тройные или более оси не очень хорошо реализованы в R. Мне не нужна двойная ось y, как в двойной шкале дополнительной решетки. Мне нужна двойная или тройная ось x. Я не мог найти способ использовать doubleYScale в свою пользу. Возможно, это возможно. Помощь будет оценена очень много.Двойная ось x (аналоговая к двойной шкале) с дополнительной решеткой или аналогичной

Это то, что я сейчас на основе данных:

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

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

Важное обновление: Я забыл упомянуть, что значения глубины на оси y обоих наборов данных разнесены друг от друга.

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

enter image description here

Что мне нужно именно так, за исключением, что розовые данных (Fluo) нуждается в его собственной оси. Гистограмма должна быть такой, но на самом деле я бы хотел, чтобы ось y была обращена так, что 0 находится наверху. Фактические данные также содержат больше станций, поэтому они будут похожи на 8 панелей данных.

С нетерпением ждем, что с этим можно сделать! Спасибо большое!


EDIT: Добавлен пример. См. Здесь:

enter image description here PS. Я не говорю, что хочу что-то похожее на это. Или слишком много осей. Но два x были бы хороши -.-

+1

Не могли бы вы включить ссылку на фигуру того типа, который вы ищете? (Мне было бы особенно интересно увидеть один с тройной осью x.) –

+0

Большое спасибо. Хорошая точка зрения. Я добавил пример. См. Выше! –

ответ

2

Насколько я знаю, нет никакого расфасованного решения более общего вопроса здесь.

В приведенном ниже примере представлены несколько подходов к добавлению дополнительной оси. Второй и более общий подход (который я хотел бы использовать даже при добавлении оси вдоль границы графика) работает, сначала нажимая окно просмотра, а затем добавляя ось вдоль ее края. Нажав на экран высотой в дюймах (например), вы можете создать ось, которая плавает на дюйм над графиком. Нажатие видового экрана с помощью прилагаемого аргумента 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))) 

enter image description here


Дополнительное примечание, в основном для себя:

Код выше, требует звонки как 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") будет строить базовый уровень, который нам бы хотелось.

+0

Спасибо за это! –