This script plots a given implicit function in two ways:
- Using plotly’s contour.
- Using plotly’s scatter plot.
If a function is given implicitly, i.e. without an explicit formula y = f(x), but with an implicit equation F(x,y) = 0, usually it is not possible to obtain from this form, by algebraic methods, the plain explicit first relation, generally required for its direct use by the plotting applications.
In such cases, as the function z = F(x,y) corresponds to a 3D surface, its intersection with the z = 0 plane gives the desired graphical relation between x and y.
To find this intersection, most programming languages, as R in this case, provides the contour function, which gives the isoclines describing the surface, from which we’ll take specifically the level-0 one.
Likewise, plotly includes contour as an option type of plot.
In the first section of this work, we’ll build a 3-column matrix, containing the (x,y,z) coordinates of surface points, enough to obtain, from the contour type of plot, the shape of the 0-level curve, that appears as the border between two colored regions (corresponding, one to positive z, and the other to negative z).
After loading some necessary libraries, we define the implicit equation and the corresponding ranges:
h <- function(x,y){(y^2 - x^2 - 0.5*exp(-x*y))}
texth <- "0 = y^2 - x^2 - 0.5 e^(-x.y)" # (I gave up trying Latex typesetting)
x1 <- seq(-1.5,2.5,0.01);y1 = seq(-2.0,2.0,0.01)
Then, we generate the cartesian product x1 X y1 as a dataframe:
xy <- meshgrid(x1,y1)
x <- xy$x; y <- xy$y
fh <- h(x,y)
mtrx2d <- expand.grid(x1,y1)
isoc <- as.data.frame(matrix(fh, nrow = prod(dim(fh))))
Build an output matrix with each point (x,y,z) on the surface to plot
consol <- cbind.data.frame(mtrx2d,isoc)
names(consol) <- c('x','y','z')
Using contour, plot the z=0 shape.
p <- plot_ly(consol, x = ~x, y=~y, z=~z, type = "contour", ncontours = 1
, width = 600, height = 400) %>%
layout(title= "Plotting an implicit function", xaxis = list(title = texth))
p
Extracting the points on the 0-contour it is possible to do a scatter plot: The function is represented by those points whose z coordinate is zero. However, we should consider the computer floating point inaccuracy, so we set a z tolerance. Build a new data frame, only in 2D, with the extracted 0-contour:
tolz <- 0.025
consol <- consol[sapply(abs(consol[,3]),function(x){x < tolz}),1:2]
Plot it as a scatter plot:
pp <- plot_ly(consol, x = ~x, y = ~y, type = "scatter", mode = "markers",
marker = list(size = 3, color = 'rgba(255, 182, 193, .9)'),
width = 600, height = 400) %>%
layout(title= "Plotting an implicit function", xaxis = list(title = texth))
pp
Now we have the same former graph, in scatter format.
If necessary, we could include more than one function in the same plot, whereas it wouldn’t be possible using the contour type of plot.
This technique could be used, for instance, to develop an interactive process for solving non-linear two-equations systems by the iterative Newton’s method.