Hello,
I am using e1071 to run support vector machine. I would like to plot
the data with lattice and specifically show the hyperplanes created by
the system.
I can store the hyperplane as a contour in an object, and I can plot
one object at a time. Since there will be thousands of elements to
plot, I can't manually add them one by one to the plot, so I tried to
loop into them, but only the last is added.
Here it the working example for more clarity:
```
library(e1071)
library(lattice)
library(latticeExtra)
make.grid <- function(x, n = 1000) {
grange = apply(x, 2, range)
x1 = seq(from = grange[1,1], to = grange[2,1], length = n)
x2 = seq(from = grange[1,2], to = grange[2,2], length = n)
expand.grid(X1 = x1, X2 = x2)
}
plot_list <- list()
for (i in 1:10) {
x1 = rnorm(100, mean = 0.2, sd = 0.15)
y1 = rnorm(100, mean = 0.7, sd = 0.15)
y2 = rnorm(100, mean = 0.2, sd = 0.15)
x2 = rnorm(100, mean = 0.75, sd = 0.15)
df = data.frame(x = c(x1,x2), y=c(y1,y2),
z=c(rep(0, length(x1)), rep(1, length(x2))))
df$z = factor(c(rep(0, length(x1)), rep(1, length(x2))))
df[, "train"] <- ifelse(runif(nrow(df)) < 0.8, 1, 0)
trainset <- df[df$train == 1, ]
testset <- df[df$train == 0, ]
trainColNum <- grep("train", names(df))
trainset <- trainset[, -trainColNum]
testset <- testset[, -trainColNum]
svm_model <- svm(z ~ .,
data = trainset,
type = "C-classification",
kernel = "linear",
scale = FALSE)
# generate contour
xmat = make.grid(matrix(c(testset$x, testset$y),
ncol = 2, byrow=FALSE))
xgrid = as.data.frame(xmat)
names(xgrid) = c("x", "y")
z = predict(svm_model, xgrid)
xyz_dat = as.data.frame(cbind(xgrid, z))
plot_list[[i]] = contourplot(z ~ y+x, data=xyz_dat, pretty = TRUE,
xlim=c(-1,50), ylim=c(-0.001, 0.05),
labels = FALSE, col = "blue", lwd =
0.5)
}
# the contour is stored in the object plot_list
str(plot_list) # confirm that there is data here
# I can add one element at the time to lattice's xyplot and store it
in an object P
P = xyplot(y ~ x, group = z, data = df,
pch = 16, cex = 1.5, alpha = 0.25) + as.layer(plot_list[[1]]) +
as.layer(plot_list[[2]])
plot(P) # this demonstrates that the lines are not the same
# but if I add the elements via loop, it does not work
for (i in 1:length(plot_list)) {
print(i)
P = xyplot(y ~ x, group = z, data = df,
pch = 16, cex = 1.5, alpha = 0.25) + as.layer(plot_list[[i]])
}
plot(P)
```
Am I missing something?
Thank you
Hi: I think you're writing over the plots so only the last one exists. Maybe try P = P + whatever but I'm not sure if that's allowed with plots. On Tue, Oct 27, 2020 at 8:34 AM Luigi Marongiu <marongiu.luigi at gmail.com> wrote:> Hello, > I am using e1071 to run support vector machine. I would like to plot > the data with lattice and specifically show the hyperplanes created by > the system. > I can store the hyperplane as a contour in an object, and I can plot > one object at a time. Since there will be thousands of elements to > plot, I can't manually add them one by one to the plot, so I tried to > loop into them, but only the last is added. > Here it the working example for more clarity: > > ``` > library(e1071) > library(lattice) > library(latticeExtra) > > make.grid <- function(x, n = 1000) { > grange = apply(x, 2, range) > x1 = seq(from = grange[1,1], to = grange[2,1], length = n) > x2 = seq(from = grange[1,2], to = grange[2,2], length = n) > expand.grid(X1 = x1, X2 = x2) > } > > plot_list <- list() > for (i in 1:10) { > x1 = rnorm(100, mean = 0.2, sd = 0.15) > y1 = rnorm(100, mean = 0.7, sd = 0.15) > y2 = rnorm(100, mean = 0.2, sd = 0.15) > x2 = rnorm(100, mean = 0.75, sd = 0.15) > df = data.frame(x = c(x1,x2), y=c(y1,y2), > z=c(rep(0, length(x1)), rep(1, length(x2)))) > df$z = factor(c(rep(0, length(x1)), rep(1, length(x2)))) > df[, "train"] <- ifelse(runif(nrow(df)) < 0.8, 1, 0) > trainset <- df[df$train == 1, ] > testset <- df[df$train == 0, ] > trainColNum <- grep("train", names(df)) > trainset <- trainset[, -trainColNum] > testset <- testset[, -trainColNum] > svm_model <- svm(z ~ ., > data = trainset, > type = "C-classification", > kernel = "linear", > scale = FALSE) > # generate contour > xmat = make.grid(matrix(c(testset$x, testset$y), > ncol = 2, byrow=FALSE)) > xgrid = as.data.frame(xmat) > names(xgrid) = c("x", "y") > z = predict(svm_model, xgrid) > xyz_dat = as.data.frame(cbind(xgrid, z)) > plot_list[[i]] = contourplot(z ~ y+x, data=xyz_dat, pretty = TRUE, > xlim=c(-1,50), ylim=c(-0.001, 0.05), > labels = FALSE, col = "blue", lwd = 0.5) > > } > # the contour is stored in the object plot_list > str(plot_list) # confirm that there is data here > > # I can add one element at the time to lattice's xyplot and store it > in an object P > P = xyplot(y ~ x, group = z, data = df, > pch = 16, cex = 1.5, alpha = 0.25) + as.layer(plot_list[[1]]) + > as.layer(plot_list[[2]]) > plot(P) # this demonstrates that the lines are not the same > > # but if I add the elements via loop, it does not work > for (i in 1:length(plot_list)) { > print(i) > P = xyplot(y ~ x, group = z, data = df, > pch = 16, cex = 1.5, alpha = 0.25) + as.layer(plot_list[[i]]) > } > plot(P) > ``` > > Am I missing something? > Thank you > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
On Tue, Oct 27, 2020 at 6:04 PM Luigi Marongiu <marongiu.luigi at gmail.com> wrote:> > Hello, > I am using e1071 to run support vector machine. I would like to plot > the data with lattice and specifically show the hyperplanes created by > the system. > I can store the hyperplane as a contour in an object, and I can plot > one object at a time. Since there will be thousands of elements to > plot, I can't manually add them one by one to the plot, so I tried to > loop into them, but only the last is added. > Here it the working example for more clarity: > > ``` > library(e1071) > library(lattice) > library(latticeExtra) > > make.grid <- function(x, n = 1000) { > grange = apply(x, 2, range) > x1 = seq(from = grange[1,1], to = grange[2,1], length = n) > x2 = seq(from = grange[1,2], to = grange[2,2], length = n) > expand.grid(X1 = x1, X2 = x2) > } > > plot_list <- list() > for (i in 1:10) { > x1 = rnorm(100, mean = 0.2, sd = 0.15) > y1 = rnorm(100, mean = 0.7, sd = 0.15) > y2 = rnorm(100, mean = 0.2, sd = 0.15) > x2 = rnorm(100, mean = 0.75, sd = 0.15) > df = data.frame(x = c(x1,x2), y=c(y1,y2), > z=c(rep(0, length(x1)), rep(1, length(x2)))) > df$z = factor(c(rep(0, length(x1)), rep(1, length(x2)))) > df[, "train"] <- ifelse(runif(nrow(df)) < 0.8, 1, 0) > trainset <- df[df$train == 1, ] > testset <- df[df$train == 0, ] > trainColNum <- grep("train", names(df)) > trainset <- trainset[, -trainColNum] > testset <- testset[, -trainColNum] > svm_model <- svm(z ~ ., > data = trainset, > type = "C-classification", > kernel = "linear", > scale = FALSE) > # generate contour > xmat = make.grid(matrix(c(testset$x, testset$y), > ncol = 2, byrow=FALSE)) > xgrid = as.data.frame(xmat) > names(xgrid) = c("x", "y") > z = predict(svm_model, xgrid) > xyz_dat = as.data.frame(cbind(xgrid, z)) > plot_list[[i]] = contourplot(z ~ y+x, data=xyz_dat, pretty = TRUE, > xlim=c(-1,50), ylim=c(-0.001, 0.05), > labels = FALSE, col = "blue", lwd = 0.5) > > } > # the contour is stored in the object plot_list > str(plot_list) # confirm that there is data here > > # I can add one element at the time to lattice's xyplot and store it > in an object P > P = xyplot(y ~ x, group = z, data = df, > pch = 16, cex = 1.5, alpha = 0.25) + as.layer(plot_list[[1]]) + > as.layer(plot_list[[2]]) > plot(P) # this demonstrates that the lines are not the same > > # but if I add the elements via loop, it does not work > for (i in 1:length(plot_list)) { > print(i) > P = xyplot(y ~ x, group = z, data = df, > pch = 16, cex = 1.5, alpha = 0.25) + as.layer(plot_list[[i]]) > } > plot(P) > ``` > > Am I missing something?Yes, as Mark says, you need to change the last part to something like P = xyplot(y ~ x, group = z, data = df, pch = 16, cex = 1.5, alpha = 0.25) for (i in 1:length(plot_list)) { print(i) P = P + as.layer(plot_list[[i]]) } plot(P) -Deepayan> Thank you > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
Awesome, thanks! On Wed, Oct 28, 2020 at 7:00 AM Deepayan Sarkar <deepayan.sarkar at gmail.com> wrote:> > On Tue, Oct 27, 2020 at 6:04 PM Luigi Marongiu <marongiu.luigi at gmail.com> wrote: > > > > Hello, > > I am using e1071 to run support vector machine. I would like to plot > > the data with lattice and specifically show the hyperplanes created by > > the system. > > I can store the hyperplane as a contour in an object, and I can plot > > one object at a time. Since there will be thousands of elements to > > plot, I can't manually add them one by one to the plot, so I tried to > > loop into them, but only the last is added. > > Here it the working example for more clarity: > > > > ``` > > library(e1071) > > library(lattice) > > library(latticeExtra) > > > > make.grid <- function(x, n = 1000) { > > grange = apply(x, 2, range) > > x1 = seq(from = grange[1,1], to = grange[2,1], length = n) > > x2 = seq(from = grange[1,2], to = grange[2,2], length = n) > > expand.grid(X1 = x1, X2 = x2) > > } > > > > plot_list <- list() > > for (i in 1:10) { > > x1 = rnorm(100, mean = 0.2, sd = 0.15) > > y1 = rnorm(100, mean = 0.7, sd = 0.15) > > y2 = rnorm(100, mean = 0.2, sd = 0.15) > > x2 = rnorm(100, mean = 0.75, sd = 0.15) > > df = data.frame(x = c(x1,x2), y=c(y1,y2), > > z=c(rep(0, length(x1)), rep(1, length(x2)))) > > df$z = factor(c(rep(0, length(x1)), rep(1, length(x2)))) > > df[, "train"] <- ifelse(runif(nrow(df)) < 0.8, 1, 0) > > trainset <- df[df$train == 1, ] > > testset <- df[df$train == 0, ] > > trainColNum <- grep("train", names(df)) > > trainset <- trainset[, -trainColNum] > > testset <- testset[, -trainColNum] > > svm_model <- svm(z ~ ., > > data = trainset, > > type = "C-classification", > > kernel = "linear", > > scale = FALSE) > > # generate contour > > xmat = make.grid(matrix(c(testset$x, testset$y), > > ncol = 2, byrow=FALSE)) > > xgrid = as.data.frame(xmat) > > names(xgrid) = c("x", "y") > > z = predict(svm_model, xgrid) > > xyz_dat = as.data.frame(cbind(xgrid, z)) > > plot_list[[i]] = contourplot(z ~ y+x, data=xyz_dat, pretty = TRUE, > > xlim=c(-1,50), ylim=c(-0.001, 0.05), > > labels = FALSE, col = "blue", lwd = 0.5) > > > > } > > # the contour is stored in the object plot_list > > str(plot_list) # confirm that there is data here > > > > # I can add one element at the time to lattice's xyplot and store it > > in an object P > > P = xyplot(y ~ x, group = z, data = df, > > pch = 16, cex = 1.5, alpha = 0.25) + as.layer(plot_list[[1]]) + > > as.layer(plot_list[[2]]) > > plot(P) # this demonstrates that the lines are not the same > > > > # but if I add the elements via loop, it does not work > > for (i in 1:length(plot_list)) { > > print(i) > > P = xyplot(y ~ x, group = z, data = df, > > pch = 16, cex = 1.5, alpha = 0.25) + as.layer(plot_list[[i]]) > > } > > plot(P) > > ``` > > > > Am I missing something? > > Yes, as Mark says, you need to change the last part to something like > > P = xyplot(y ~ x, group = z, data = df, pch = 16, cex = 1.5, alpha = 0.25) > for (i in 1:length(plot_list)) { > print(i) > P = P + as.layer(plot_list[[i]]) > } > plot(P) > > -Deepayan > > > Thank you > > > > ______________________________________________ > > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > > https://stat.ethz.ch/mailman/listinfo/r-help > > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > > and provide commented, minimal, self-contained, reproducible code.-- Best regards, Luigi