Подтвердить что ты не робот

Как нарисовать эффект "увеличения" в R

enter image description here

В качестве карты эскиза выше вы можете представить, что верхний - это график пространства параметров, например, среднее значение и дисперсия для нормального распределения, а нижний - соответствующий график плотности. Любые подсказки для этого? Спасибо ~

ОБНОВЛЕНИЕ. В качестве улучшения можно создать интерактивную версию для этого? Скажем, всякий раз, когда я нажимаю над точкой, R показывает соответствующий график внизу.

4b9b3361

Ответ 1

Вот интерактивная версия, вы можете щелкнуть по точке, а затем появится соответствующий график плотности. В основном используется ?identify и как @Tyler предложил ?zoomInPlot.

Более подробная информация о том, как это работает: rxlim и rylim, определенные в самом начале, - это размер прямоугольника, который окружает выбранную точку, поэтому можно изменить коэффициент /20. Возможность нескольких кликов нетривиальна: identify() обнаруживает клики только в "недавнем" графике, т.е.

par(mfrow = c(1,2))
plot(1:10) # 1
plot(1:10) # 2
identifyPch(1:10)

обнаруживает клики только на графике # 2 (здесь identifyPch() от ?identify). Для этой проблемы использовался par(mfg=c(1, 1)):

MFG

Числовой вектор формы c (i, j), где я и j указывают которая фигурирует в массиве цифр, должна быть следующей (если настройка) или втягивается (если запрашивается). Массив уже должен быть установлен по mfcol или mfrow.

enter image description here

zoom <- function (x, y, xlim, ylim, xd, yd) 
{
  rxlim <- x + c(-1, 1) * (diff(range(xd))/20)
  rylim <- y + c(-1, 1) * (diff(range(yd))/20)
  par(mfrow = c(1, 2))
  plot(xd, yd, xlab = "mean", ylab = "sd")
  xext <- yext <- rxext <- ryext <- 0
  if (par("xaxs") == "r") {
    xext <- diff(xlim) * 0.04
    rxext <- diff(rxlim) * 0.04
  }
  if (par("yaxs") == "r") {
    yext <- diff(ylim) * 0.04
    ryext <- diff(rylim) * 0.04
  }
  rect(rxlim[1] - rxext, rylim[1] - ryext, rxlim[2] + rxext, 
       rylim[2] + ryext)
  xylim <- par("usr")
  xypin <- par("pin")
  rxi0 <- xypin[1] * (xylim[2] - (rxlim[1] - rxext))/diff(xylim[1:2])
  rxi1 <- xypin[1] * (xylim[2] - (rxlim[2] + rxext))/diff(xylim[1:2])
  y01i <- xypin[2] * (xylim[4] - (rylim[2] + ryext))/diff(xylim[3:4])
  y02i <- xypin[2] * ((rylim[1] - ryext) - xylim[3])/diff(xylim[3:4])
  mu <- x
  curve(dnorm(x, mean = mu, sd = y), from = -4 * y + mu, to = 4 * y + mu, 
        xlab = paste("mean:", round(mu, 2), ", sd: ", round(y, 2)), ylab = "")
  xypin <- par("pin")
  par(xpd = NA)
  xylim <- par("usr")
  xymai <- par("mai")
  x0 <- xylim[1] - diff(xylim[1:2]) * (xymai[2] + xymai[4] + 
                                         rxi0)/xypin[1]
  x1 <- xylim[1] - diff(xylim[1:2]) * (xymai[2] + xymai[4] + 
                                         rxi1)/xypin[1]
  y01 <- xylim[4] - diff(xylim[3:4]) * y01i/xypin[2]
  y02 <- xylim[3] + diff(xylim[3:4]) * y02i/xypin[2]
  par(xpd = TRUE)
  xend <- xylim[1] - diff(xylim[1:2]) * xymai[2]/(2 * xypin[1])
  xprop0 <- (xylim[1] - xend)/(xylim[1] - x0)
  xprop1 <- (xylim[2] - xend)/(xylim[2] - x1)
  par(xpd = NA)
  segments(c(x0, x0, x1, x1), 
           c(y01, y02, y01, y02), 
           c(xend, xend, xend, xend), 
           c(xylim[4] - (xylim[4] - y01) * xprop0, 
             xylim[3] + (y02 - xylim[3]) * xprop0, 
             xylim[4] - (xylim[4] - y01) * xprop1, 
             xylim[3] + (y02 - xylim[3]) * xprop1))
  par(mfg = c(1, 1))
  plot(xd, yd, xlab = "mean", ylab = "sd")
}

ident <- function(x, y, ...)
{
  ans <- identify(x, y, n = 1, plot = FALSE, ...)
  if(length(ans)) {
    zoom(x[ans], y[ans], range(x), range(y), x, y)
    points(x[ans], y[ans], pch = 19)
    ident(x, y)
  }
}

x <- rnorm(10)
y <- rnorm(10, mean = 5)
par(mfrow = c(1, 2))
plot(x, y, xlab = "mean", ylab = "sd")
ident(x, y)

Ответ 2

iplots пакет близок к этому, хотя там технически нет "масштабирования". iplots имеет интерактивные связанные сюжеты, реализованные с помощью графического интерфейса Java. Вы можете выбрать точки на одном графике, и те же очки будут выделены на других участках. Сайт для пакета здесь.

library(iplots)
data(Cars93)
iplot(Cars93$Horsepower, Cars93$MPG.city)
ihist(Cars93$Horsepower)

Здесь я выбрал несколько точек в левой диаграмме рассеяния, превратив их в красный цвет, и они также становятся выделенными на правой гистограмме (гистограмма ближе всего к графику плотности).

enter image description here