График поверхности RGL из фрейма данных

Я создал красивый сюжет, используя scatter3d() и Rcmdr. Этот сюжет содержит две красивые гладкие поверхности. Теперь я хотел бы добавить к этому графику еще одну поверхность, истину (т.е. поверхность, определенную функцией, генерирующей мои наблюдения, за вычетом шумовой составляющей).

Вот мой код:

library(car) 
set.seed(1)

n <- 200 # number of observations (x,y,z) to be generated
sd <- 0.3 # standard deviation for error term
x <- runif(n) # generate x component
y <- runif(n) # generate y component

r <- sqrt(x^2+y^2) # used to compute z values

z_t <- sin(x^2+3*y^2)/(0.1+r^2) + (x^2+5*y^2)*exp(1-r^2)/2 # calculate values of true regression function

z <-  z_t + rnorm(n, sd = sd) # overlay normally distrbuted 'noise' 
dm <- data.frame(x=x, y=y, z=z) # data frame containing (x,y,z) observations
dm_t <- data.frame(x=x,y=y, z=z_t) # data frame containing (x,y) observations and the corresponding value of the *true* regression function

# Create 3D scatterplot of:
# - Observations (this includes 'noise')
# - Surface given by Additive Model fit 
# - Surface given by bivariate smoother fit

scatter3d(dm$x, dm$y, dm$z, fit=c("smooth","additive"), bg="white", 
          axis.scales=TRUE, grid=TRUE, ellipsoid=FALSE, xlab="x", ylab="z", zlab="y")

Решение, данное в другом потоке, состоит в том, чтобы затем определить функцию:

my_surface <- function(f, n=10, ...) { 
  ranges <- rgl:::.getRanges()
  x <- seq(ranges$xlim[1], ranges$xlim[2], length=n)
  y <- seq(ranges$ylim[1], ranges$ylim[2], length=n)
  z <- outer(x,y,f)
  surface3d(x, y, z, ...)
}

f <- function(x, y)
  sin(x^2+3*y^2)/(0.1+r^2) + (x^2+5*y^2)*exp(1-r^2)/2

my_surface(f, alpha=0.2)

Однако это приводит к ошибке, в которой говорится (в переводе с немецкого, поскольку это мой системный язык, прошу прощения):

Error in outer(x, y, f) : 
  Dimension [Product 100] does not match the length of the object [200]

Затем я попробовал альтернативный подход:

x <- seq(0,1,length=20)
y <- x
z <- outer(x,y,f)
surface3d(x,y,z)

Это добавляет поверхности к моему графику, но выглядит совсем не так (т.е. наблюдения даже не близки к этому). Вот как выглядит предполагаемая истинная поверхность (это явно неверно): Спасибо!

Неправильная истинная поверхность регрессии

Думаю, проблема на самом деле может быть в масштабировании. Здесь я создал пару точек на плоскости z = x + y. Затем я попытался построить эту плоскость, используя описанный выше метод:

library(car)

n <- 50
x <- runif(n)
y <- runif(n)
z <- x+y

scatter3d(x,y,z, surface = FALSE)

f <- function(x,y) 
  x + y 

x_grid <- seq(0,1, length=20)
y_grid <- x_grid 
z_grid <- outer(x_grid, y_grid, f)
surface3d(x_grid, y_grid, z_grid)

Это дает мне следующий сюжет:

Проблема масштабирования

Может, кто-нибудь из вас поможет мне с этим?


person user2249626    schedule 14.08.2013    source источник
comment
Вы задали аналогичный вопрос, на который получили хороший ответ, но вы никогда не голосовали и не принимали ответ. Это заставит людей отказываться помогать вам, потому что вы ничего не отдаете сообществу. Прочтите Справку и О, чтобы узнать, как предполагается работать SO.   -  person Simon O'Hanlon    schedule 14.08.2013
comment
@HaskellElephant Я никогда ничего не говорил о моем выборе. Я просто указал на то, что люди могут не захотеть помочь, если увидят, что пользователь никогда не указывал. Откуда вы пришли к такому выводу? Кроме того, в тот момент, когда я оставил комментарий, вопрос не включал ни кода, ни воспроизводимого примера. Теперь я вижу, что ОП оставил отличный воспроизводимый пример и лучше понимает сообщество, потому что они приняли ответ (который, по их собственному признанию, решил их проблему). Так что мой комментарий обогатил сообщество и опыт OP. Больше вовлеченности = лучше.   -  person Simon O'Hanlon    schedule 14.08.2013
comment
+1 за то, что нашли время редактировать этот вопрос. Теперь это отличный воспроизводимый пример.   -  person Simon O'Hanlon    schedule 14.08.2013


Ответы (1)


Функция scatter3d в car масштабирует данные перед их построением, что делает их несовместимыми практически со всеми rgl функциями построения графиков, включая surface3d.

Вы можете получить что-то вроде того, что хотите, используя все rgl функции, например plot3d(x, y, z) вместо scatter3d, но, конечно, у него будут оси в стиле rgl, а не в стиле car.

person user2554330    schedule 25.06.2016