Argument is missing while trying to add surface (R) - r

I am trying to run these functions to establish a 3D plot and I want to add a plane but an error occurs.
plot_ly(data = df, z = ~PM, x = ~Wind_speed, y = ~SO2, opacity = 0.5) %>%
add_markers()
x <- seq(370, 15000, by = 10)
y <- seq(0, 15000, by = 10)
plane <- outer(x, y, function(a, b){fit$coef[1] +
fit$coef[2]*a + fit$coef[3]*b})
add_surface(x = ~x, y = ~y, z = ~plane, showscale = FALSE)
but then this error shows up
> add_surface(x = ~x, y = ~y, z = ~plane, showscale = FALSE)
Error in add_trace_classed(p, class = "plotly_surface", z = z, type = "surface", :
argument "p" is missing, with no default
What should I do to fix this?

I do not know how it got solved but I could fix it somehow. I just reloaded the data, changed the order of the functions and wrote these functions together:
x <- seq(370, 15000, by = 10)
y <- seq(0, 15000, by = 10)
plane <- outer(x, y, function(a, b){fit$coef[1] +
fit$coef[2]*a + fit$coef[3]*b})
plot_ly(data = df, z = ~PM, x = ~Wind_speed, y = ~SO2, opacity = 0.5) %>%
add_markers()
add_surface(x = ~x, y = ~y, z = ~plane, showscale = FALSE)

Related

Surface of a matrix with plotly in R distorted

I have the following code example in R to visualize a surface generated as an interpolation from points.
library(plotly)
test_data=read.csv("test_data.csv")
x<- test_data$x
y<- test_data$y
z<- test_data$z
fit_loess=loess(z ~ x + y , degree = 0,span=0.54)
min_x <- min(x)
max_x <- max(x)
min_y <- min(y)
max_y <- max(y)
griddf <- expand.grid(x = (seq(min_x,max_x,length.out = 10)),
y = (seq(min_y,max_y,length.out = 10)))
p_loess <- data.frame(griddf)
p_loess$z <- predict(fit_loess, p_loess)
fig <- plot_ly()
fig <- fig %>% add_surface(z = ~xtabs(z ~ x + y, data = p_loess),
x = seq(min_x,max_x,length.out = 10),
y =seq(min_y,max_y,length.out = 10),colorbar=list(title = 'z'))
fig <- fig %>% add_markers( x = ~x, y = ~y, z = ~z,
marker = list(color = 'rgb(17, 157, 255)',size = 3))
fig
According my question in Question ID 73946202 , I am using xtabs for matrix generation.
But the result of the surface of plotly is distorted to the measurement points. I am not able to find the reason for that.
test_data.csv:
"","x","y","z"
"1",1.97494896,9.99449486,54.9318
"2",1.97493756666667,9.9945128,54.970222222222
"3",1.97492473333333,9.9945292333333,55.060666666667
"4",1.97491141666667,9.9945450333333,55.415
"5",1.97489883333333,9.9945608833333,55.639666666667
"6",1.97488585,9.99457735,55.742166666667
"7",1.97487323333333,9.9945934166667,55.772333333333
"8",1.97486086666667,9.9946095833333,55.953333333333
"9",1.97485151666667,9.99462525,55.970166666667
"10",1.97483576666667,9.9946413166667,56.0495
"11",1.97506965,9.9945288666667,55.070333333333
"12",1.9750572,9.99454545,55.196666666667
"13",1.97504416666667,9.9945614,55.305
"14",1.97503078333333,9.9945772833333,55.375166666667
"15",1.97501828333333,9.9945933333333,55.5
"16",1.97500516666667,9.9946096666667,55.615333333333
"17",1.97499288333334,9.9946255833333,55.725
"18",1.97498116666667,9.9946405166667,55.766333333333
"19",1.97496823333333,9.9946565833333,55.781333333333
"20",1.97495426666667,9.9946739166667,56.014333333333

How to put plotmath labels in ggplot facets

We often want individual regression equations in ggplot facets. The best way to do this is build the labels in a dataframe and then add them manually. But what if the labels contain plotmath, e.g., superscripts?
Here is a way to do it. The plotmath is converted to a string and then parsed by ggplot. The test_eqn function is taken from another Stackoverflow post, I'll link it when I find it again. Sorry about that.
library(ggplot2)
library(dplyr)
test_eqn <- function(y, x){
m <- lm(log(y) ~ log(x)) # fit y = a * x ^ b in log space
p <- exp(predict(m)) # model prediction of y
eq <- substitute(expression(Y==a~X^~b),
list(
a = format(unname(exp(coef(m)[1])), digits = 3),
b = format(unname(coef(m)[2]), digits = 3)
))
list(eq = as.character(eq)[2], pred = p)
}
set.seed(123)
x <- runif(20)
y <- runif(20)
test_eqn(x,y)$eq
#> [1] "Y == \"0.57\" ~ X^~\"0.413\""
data <- data.frame(x = x,
y = y,
f = sample(c("A","B"), 20, replace = TRUE)) %>%
group_by(f) %>%
mutate(
label = test_eqn(y,x)$eq, # add label
labelx = mean(x),
labely = mean(y),
pred = test_eqn(y,x)$pred # add prediction
)
# plot fits (use slice(1) to avoid multiple copies of labels)
ggplot(data) +
geom_point(aes(x = x, y = y)) +
geom_line(aes(x = x, y = pred), colour = "red") +
geom_text(data = slice(data, 1), aes(x = labelx, y = labely, label = label), parse = TRUE) +
facet_wrap("f")
Created on 2021-10-20 by the reprex package (v2.0.1)

Issues on using R's "rgl" and "car" for 3D scatter plot and multiple regression

I am working on plotting a scatter plot of three variables and a multiple regression with two covariates using R's "rgl" and "car" package.
I have three issues:
I can't change the background color from black to white.
I can't rotate objects without the image becoming messy.
When running the code for the multiple regression plot, several errors show up, despite using code from a tutorial on the subject (link below).
For 1 and 2 I have tried:
rgl.open()
rgl.bg(color = "white")
rgl.points(x, y, z, color = "blue", size = 5) # Scatter plot
and:
bg3d("white")
scatter3d(x = x, y = y, z = z)
scatter3d(x = x, y = y, z = z,
point.col = "blue", surface=FALSE)
In both cases I get this result:
and when rotating:
For 3, I have used the following code (from here) which returns two errors:
>rgl_init()
**Error in rgl_init() : could not find function "rgl_init"**
> rgl.spheres(x, y, z, r = 0.2, color = "#D95F02")
> rgl_add_axes(x, y, z, show.bbox = FALSE)
**Error in rgl_add_axes(x, y, z, show.bbox = FALSE) :
could not find function "rgl_add_axes"**
> aspect3d(1,1,1)
> # Compute the linear regression (y = ax + bz + d)
> fit <- lm(y ~ x + z)
> # predict values on regular xz grid
> grid.lines = 12
> x.pred <- seq(min(x), max(x), length.out = grid.lines)
> z.pred <- seq(min(z), max(z), length.out = grid.lines)
> xz <- expand.grid( x = x.pred, z = z.pred)
> y.pred <- matrix(predict(fit, newdata = xz),
+ nrow = grid.lines, ncol = grid.lines)
> # Add regression surface
> rgl.surface(x.pred, z.pred, y.pred, color = "steelblue",
+ alpha = 0.5, lit = FALSE)
> # Add grid lines
> rgl.surface(x.pred, z.pred, y.pred, color = "black",
+ alpha = 0.5, lit = FALSE, front = "lines", back = "lines")

Plotly Contour plot behaviour

I want to understand how to correctly do contour plots with plotly. In the code below I have x,y,z so I interpolate to have a more defined range with the interp in akima package. I plot the result first with plotly then with filled.contour. The result of the plotly is wrong but I like more its aesthetics in the filled contour the results is correct.
What am I doing wrong with plotly?
require(akima)
require(plotly)
x = rand(15,1)
y = rand(15,1)
z = rand(15,1)
a = interp(x, y, z)
p = plot_ly(x = a$x,
y = a$y,
z = a$z,
type = "contour")
p
filled.contour(a$x,a$y,a$z)
Plotly expects a little bit different matrix arrangement. Here is a fix:
require(akima)
require(plotly)
library(pracma)
set.seed(1)
x = rand(15,1)
y = rand(15,1)
z = rand(15,1)
a = interp(x, y, z)
plot_ly(x = a$x,
y = a$y,
z = matrix(a$z, nrow = length(a$y), byrow = TRUE),
type = "contour")
filled.contour(a$x,a$y,a$z)
without the matrix rearrangement:
plot_ly(x = a$x,
y = a$y,
z = a$z,
type = "contour")

Plot vectors of gradient descent in R

I've code gradient descent algorithm in R and now I'm trying to "draw" the path of the vectors.
I've got draw points in my contour plot, but it's not correct because nobody knows what happened first.
In my algorith always I have an previous state P=(Xi,Yi) and a later state L=(Xi+1,Yi+1), so, How can I draw the vector PL in a contour or a persp plot?
I only got this with contour, where the red point is the convergence:
The same for persp:
Thanks all!
EDIT:
Graphics can be obtanined respectively:
f<-function(u,v){
u*u*exp(2*v)+4*v*v*exp(-2*u)-4*u*v*exp(v-u)
}
x = seq(-2, 2, by = 0.5)
y = seq(-2, 2, by = 0.5)
z <- outer(x,y,f)
#Contour plot
contour(x,y,z)
#Persp plot
persp(x, y, z, phi = 25, theta = 55, xlim=c(-2,2), ylim=c(-2,2),
xlab = "U", ylab = "V",
main = "F(u,v)", col="yellow", ticktype = "detailed"
) -> res
Taking Himmelblau's function as a test example:
f <- function(x, y) { (x^2+y-11)^2 + (x+y^2-7)^2 }
Its partial derivatives:
dx <- function(x,y) {4*x**3-4*x*y-42*x+4*x*y-14}
dy <- function(x,y) {4*y**3+2*x**2-26*y+4*x*y-22}
Running the gradient descent:
# gradient descent parameters
num_iter <- 100
learning_rate <- 0.001
x_val <- 6
y_val <- 6
updates_x <- vector("numeric", length = num_iter)
updates_y <- vector("numeric", length = num_iter)
updates_z <- vector("numeric", length = num_iter)
# parameter updates
for (i in 1:num_iter) {
dx_val = dx(x_val,y_val)
dy_val = dy(x_val,y_val)
x_val <- x_val-learning_rate*dx_val
y_val <- y_val-learning_rate*dx_val
z_val <- f(x_val, y_val)
updates_x[i] <- x_val
updates_y[i] <- y_val
updates_z[i] <- z_val
}
Plotting:
x <- seq(-6, 6, length = 100)
y <- x
z <- outer(x, y, f)
plt <- persp(x, y, z,
theta = -50-log(i), phi = 20+log(i),
expand = 0.5,
col = "lightblue", border = 'lightblue',
axes = FALSE, box = FALSE,
ltheta = 60, shade = 0.90
)
points(trans3d(updates_x[1:i], updates_y[1:i], updates_z[1:i],pmat = plt),
col = c(rep('white', num_iter-1), 'blue'),
pch = 16,
cex = c(rep(0.5, num_iter-1), 1))
There's a trick to plotting points using persp, as mentioned in ?persp. By employing the power of trans3d, you can successfully put points and lines on a perspective plot.
f<-function(u,v){
u*u*exp(2*v)+4*v*v*exp(-2*u)-4*u*v*exp(v-u)
}
x = seq(-2, 2, by = 0.5)
y = seq(-2, 2, by = 0.5)
z <- scale(outer(x,y,f))
view <- persp(x, y, z, phi = 30, theta = 30, xlim=c(-2,2), ylim=c(-2,2),
xlab = "X", ylab = "Y", zlab = "Z", scale = FALSE,
main = "F(u,v)", col="yellow", ticktype = "detailed")
set.seed(2)
pts <- data.frame(x = sample(x, 3),
y = sample(y, 3),
z = sample(z, 3))
points(trans3d(x = pts$x, y = pts$y, z = pts$z, pmat = view), pch = 16)
lines(trans3d(x = pts$x, y = pts$y, z = pts$z, pmat = view))

Resources