R `contourLines` issue

26 views Asked by At

I want to plot the curve implicitly defined by f(x, y) = y^4 - y^3 + y^2 - 2*x^2*y + x^4 = 0.

It is clear that this curve is symmetric in x since f(-x, y) = f(x, y).

However, I get only one half of this curve with contourLines:

f <- function(x, y) {
  y^4 - y^3 + y^2 - 2*x^2*y + x^4
}

x <- seq(-3, 3, len = 1000)
y <- seq(-3, 3, len = 1000)
z <- outer(x, y, f)
cr <- contourLines(x, y, z, levels = 0)

library(ggplot2)
dat <- data.frame(x = cr[[1]]$x, y = cr[[1]]$y)
ggplot() + geom_path(aes(x, y), data = dat)

enter image description here

Moreover, you can check that

  • contour(x, y, z, levels = 0) plots the expected curve
  • replacing levels = 0 with levels = 0.0001 in contourLines gives a symmetric curve

What is happening? How to get the symmetric curve?

1

There are 1 answers

1
Stéphane Laurent On

I get it: str(cr) shows that cr is a list of 12 paths, and one has to plot each of them, whereas I plotted only the first one. I thought that there was one list in the output for each level.

Here is a convenient way to plot all the paths:

intercalateNA <- function(xs) {
  if(length(xs) == 1L) {
    xs[[1L]]
  } else {
    c(xs[[1L]], NA, intercalateNA(xs[-1L]))
  }
}

xs <- lapply(cr, `[[`, "x")
ys <- lapply(cr, `[[`, "y")

library(ggplot2)
dat <- data.frame(x = intercalateNA(xs), y = intercalateNA(ys))
ggplot() + geom_path(aes(x, y), data = dat)

enter image description here