R ggplot2: how do I plot an implicit function (contour line at just one level)?

拜拜、爱过 提交于 2019-12-24 04:38:08

问题


Using R, I wanted to plot some datapoints and a curve over them (which is the decision boundary trained with neural network). First I did it with the normal plot functions, but now I want it to look more fancy using ggplot2.

This is what it looks like without ggplot (note the curve especially, the points are not too relevant):

Plotting the points with ggplot is no problem, but now I want to add the curve as well, which is described by the following function:

1.91*(1/(1+exp(-(23.50+12.64*x-24.54*y))))-1.95*(1/(1+exp(-(73.51-12.36*x-10.01*y)))) + 0.98 = 0

This is a just function with two variables equated to zero, like 3x-2y=0 for example. As you can see this one is difficult to rewrite in a y=... form, so that is why I would like to plot the equation by using a contour plot at level = 0. It worked using curve3d on top of my scatterplot:

curve3d(1.91*(1/(1+exp(-(23.50+12.64*x-24.54*y))))-1.95*(1/(1+exp(-(73.51-12.36*x-10.01*y)))) + 0.98 = 0, sys3d="contour",levels=0, add=TRUE)

Now I really want to use ggplot2 to achieve the same result. I've tried the stat_contour plots, but they don't seem to take functions and will not allow to choose only one level. So:

  1. Is there any way to plot a function in equation form (like ax+by=0 but probably more complex) form using ggplot?
  2. Can I add such a plotted curve to my geom_point ggplot with datapoints?

EDIT: here is a code example recreating my data:

# data
x1 <- rnorm(200,   3,    .28)
y1 <- rnorm(200,   3,    .28)
x2 <- rnorm(100, 3.45, .15)
y2 <- rnorm(100, 3.35, .15)
x3 <- rnorm(100, 3.3,  .15)
y3 <- rnorm(100, 2.4,  .15)

groups <- c(rep("H",200), rep("A",100), rep("B",100))
data <- data.frame(x = c(x1,x2,x3), y = c(y1,y2,y3), group = groups)

# the working ggplot
windows()
ggplot(data, aes(x=x,y=y)) +  xlim(2,4) + ylim(2,4) + geom_point(aes(color = group)) + scale_shape_manual(values=c(1,16))

# the old plot that I would like to plot with ggplot over the previous one with as well (doesn't work)
curve3d(1.91*(1/(1+exp(-(23.50+12.64*x-24.54*y))))-1.95*(1/(1+exp(-(73.51-12.36*x-10.01*y)))) + 0.98, xlim=c(2,4), ylim=c(2,4), sys3d="contour",levels=0, add=TRUE)

So with this data, I would like to plot the function 1.91*(1/(1+exp(-(23.50+12.64*x-24.54*y))))-1.95*(1/(1+exp(-(73.51-12.36*x-10.01*y)))) + 0.98 = 0 (or any other implicit function, like 5x+2y=0 without having to rewrite it).


回答1:


tl;dr the only thing you were really missing was breaks=0. Base plot:

g0 <- ggplot(data, aes(x=x,y=y)) +  xlim(2,4) + ylim(2,4) +
    geom_point(aes(color = group)) + scale_shape_manual(values=c(1,16))

Generate data for contour (without drawing anything):

cc <- emdbook::curve3d(1.91*(1/(1+exp(-(23.50+12.64*x-24.54*y))))-
              1.95*(1/(1+exp(-(73.51-12.36*x-10.01*y)))) + 0.98,
              xlim=c(2,4), ylim=c(2,4), sys3d="none")

Reorganize data into a data frame:

dimnames(cc$z) <- list(cc$x,cc$y)
mm <- reshape2::melt(cc$z)

Draw with breaks=0

g0 + geom_contour(data=mm,
                  aes(x=Var1,y=Var2,z=value),breaks=0,
                  colour="black")



来源:https://stackoverflow.com/questions/40915399/r-ggplot2-how-do-i-plot-an-implicit-function-contour-line-at-just-one-level

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!