I've written a small program that draws a vector field in R using ggplot for a given differential equation.
There is a topic on the subject here however, the proposed solutions either don't provide the same functionality as the code below or don't use ggplot.
//example differential equation: f_prime = f(x,y)
f_prime <- function(x,y){
return(x^2/(1-x^2-y^2))
}
//set the min and max for the x and y curves
x <- 4 //change if you like
y <- 4
minX <- -x
maxX <- x
minY <- -y
maxY <- y
len <- 40 //number by which the x,y space will be subdivided by
//larger number => more points and vice versus
//create an equally spaced grid
data <- data.frame(expand.grid(x = seq(minX, maxX, length.out=len),
y = seq(minY, maxY, length.out=len)))
//create a new column for the results of (x,y) applied on f_prime
data$dydx <- mapply(f_prime, data$x, data$y)
A small graphic to visualize the problem:
//The next step is important to understand:
//The goal is have arrows that have approx. the same length (c = const) and
//point to the direction of f_prime at some point (x,y) for all points
//Note: f_prime is the derivative of F(x,y) with respect to x,
//hence f_prime provides the relative change in y as a result of a change in x
//Now the problem to draw the arrows can be formulated using f_prime (= dy/dx)
//and the fact that c^2 = dy^2 + dx^2 (Pythagoras)
//Using basic algebra to solve the problem:
//Solve for dx = dy/f_prime(x,y) and insert into
//c^2 = dy^2 + dx^2 = dy^2 + (dy/f_prime(x,y))^2 and solve for dx
//dx = sqrt(c^2/(1+f(x,y)^2) and
//dy = f(x,y)*dx
//now we can draw the arrows using (x,y) as the start and (x+dx, y+dy) as the end
//translating this into code:
data$dx <- sqrt((1/len)/(1+data$dydx^2))
data$dy <- data$dx*data$dydx
ggplot(data=data, aes(x=x,y=y), environment = environment()) +
geom_point(size = 1) +
geom_segment(aes(xend=x+dx, yend=y+dy), arrow = arrow(length = unit(0.1, "cm"))) +
xlim(minX,maxX) +
ylim(minY,maxY)
Looks like:
Maybe there is a better/faster more elegant way to do it, if yes please share if not happy to help.
1/len
where you hadc^2
in your notes? \$\endgroup\$