Удобная оболочка для графиков, линий и точек

Одна из вещей, которая меня больше всего беспокоит в R, это разделение команд графика, точек и линий. Несколько раздражает необходимость менять график на какой-либо вариант для первого сделанного графика и выполнять повторный график с нуля, если вы изначально не установили правильные значения ylim и xlim. Не было бы неплохо иметь одну команду, которая:

  1. Выбирает линии, точки или оба через аргумент, как в plot(..., type = "l")?

  2. По умолчанию выбирается, создавать ли новый график или добавлять к существующему в зависимости от того, является ли текущее устройство пустым или нет.

  3. Масштабирует оси автоматически, если добавленные элементы на график превышают текущие границы.

Кто-нибудь сделал что-нибудь подобное? Если нет, и нет веских причин, почему это невозможно, я сам на это отвечу немного...

2 ответа

Некоторые возможные функции, которые могут помочь с тем, что вы хотите:

matplot Функция использует базовую графику и построит несколько наборов точек или линий за один шаг, определив правильные диапазоны за один шаг.

Есть update метод для решетчатой ​​графики, который можно использовать для добавления / изменения объектов на графике и, следовательно, приведет к автоматическому пересчету таких вещей, как пределы и оси.

Если вы добавите дополнительную информацию (используя +) на график ggplot2, то вещи, которые автоматически рассчитываются, будут пересчитаны.

Вы уже нашли zoomplot и всегда есть подход написания вашей собственной функции, как вы сделали.

Во всяком случае, это то, что я придумал: (Он использует zoomplot от TeachingDemos)

 fplot <- function(x, y = NULL, type = "l", new = NULL, xlim, ylim, zoom = TRUE,...){
   require(TeachingDemos)
   if (is.null(y)){
if (length(dim(x)) == 2){
    y = x[,2]
    x = x[,1]
} else {
       y = x
       x = 1:length(y)
     } 
}

   if ( is.null(new) ){
   #determine whether to make a new plot or not
   new = FALSE
   if (is.null(recordPlot()[[1]])) new = TRUE
   }
   if (missing(xlim)) xlim = range(x)
   if (missing(ylim)) ylim = range(y)

   if (new){
   plot(x, y, type = type, xlim = xlim, ylim = ylim, ...)
   } else {
    if (type == "p"){
        points(x,y, ...)
    } else {
        lines(x,y, type = type, ...)
    }
    if (zoom){
    #rescale plot
    xcur = par("usr")[1:2]
    ycur = par("usr")[3:4]
    #shrink coordinates and pick biggest
    xcur = (xcur - mean(xcur)) /1.08 + mean(xcur)
    ycur = (ycur - mean(ycur)) /1.08 + mean(ycur)
    xlim = c(min(xlim[1], xcur[1]), max(xlim[2], xcur[2]))
    ylim = c(min(ylim[1], ycur[1]), max(ylim[2], ycur[2]))
    #zoom plot
    zoomplot(xlim, ylim)
    }
   }
 }

Так что вы можете сделать, например,

dev.new()
fplot(1:4)
fplot(1:4 +1, col = 2)
fplot(0:400/100 + 1, sin(0:400/10), type = "p")
dev.new()
for (k in 1:20) fplot(sort(rnorm(20)), type = "b", new = (k==1) )

par(mfrow) и логарифмическая ось в настоящее время плохо работают с масштабированием, но это начало...

Другие вопросы по тегам