Skip to content

Instantly share code, notes, and snippets.

@eliocamp
Last active May 14, 2019 15:21
Show Gist options
  • Select an option

  • Save eliocamp/eaee32b7a16751c851cdf4376cc0b79f to your computer and use it in GitHub Desktop.

Select an option

Save eliocamp/eaee32b7a16751c851cdf4376cc0b79f to your computer and use it in GitHub Desktop.
vector field animation
library(data.table)
library(ggplot2)
library(metR)
library(magrittr)
library(gganimate)
# Define la función que genera el campo vector
funcion_campo <- function(x, y, a, b) {
list(dx = y,
dy = a + b*x + x^2 - x*y)
}
### Un ejemplo
a <- -1
b <- 1
# Genera una grilla equiespaciada
grilla <- as.data.table(expand.grid(x = seq(-4, 4, length.out = 50),
y = seq(-4, 4, length.out = 50)))
grilla[, c("dx", "dy") := funcion_campo(x, y, a, b)]
# Plotea
ggplot(grilla, aes(x, y)) +
geom_contour(aes(z = dx), breaks = 0, color = "red") + # Nulclina de dx
geom_contour(aes(z = dy), breaks = 0, color = "red") + # Nulclina de dy
metR::geom_streamline(aes(dx = dx, dy = dy), L = 50, skip = 6, res = 1/2,
arrow.angle = 7, arrow.length = 0.6) + # Trayectorias
coord_equal(expand = FALSE, xlim = c(-3, 3), ylim = c(-3, 3)) +
theme_bw()
# Meto todo eso en una función
plot_campo <- function(a, b) {
# Mapita del espacio de parámetros
inset <- ggplot(data.frame(a = a, b = b), aes(b, a)) +
geom_vline(xintercept = 0, color = "gray") +
geom_hline(yintercept = 0, color = "gray") +
geom_point() +
ggforce::geom_circle(data = data.frame(x0 = 0, y0 =0, r = 2),
aes(x0 = x0, y0 = y0, r = r),
inherit.aes = F, size = 0.1, color = "gray20") +
stat_function(fun = function(x) x^2/4) +
ylim(c(-4, 4)) + xlim(-4, 4) +
coord_equal(xlim = c(-4, 4), ylim = c(-4, 4)) +
theme_void() +
theme(plot.background = element_rect(color = "black", fill = "white"))
# Campo
grilla <- as.data.table(expand.grid(x = seq(-4, 4, length.out = 50),
y = seq(-4, 4, length.out = 50)))
grilla[, c("dx", "dy") := funcion_campo(x, y, a, b)][]
g <- ggplot(grilla, aes(x, y)) +
geom_contour(aes(z = dx), breaks = 0, color = "red") +
geom_contour(aes(z = dy), breaks = 0, color = "red") +
metR::geom_streamline(aes(dx = dx, dy = dy), L = 50, skip = 6, res = 1/2,
arrow.angle = 7, arrow.length = 0.6) +
annotation_custom(ggplotGrob(inset), ymin = 1.5, xmin = 1.5) +
coord_equal(expand = FALSE, xlim = c(-3, 3), ylim = c(-3, 3)) +
theme_bw()
print(g)
return(g)
}
plot_campo(0, -2)
## Ahora la animación
crear_cuadros <- function(N = 120) {
# Voy a moverme en el espacio de parámetros en un círculo de radio r
r <- 2
thetas <- seq(0, 2*pi, length.out = N+1)
thetas <- thetas[-1]
a <- r*sin(thetas)
b <- r*cos(thetas)
lapply(seq_along(thetas), function(i) {
plot_campo(a[i], b[i])
})
}
gifski::save_gif(crear_cuadros(30), width = 600, height = 600, delay = 30/30,
gif_file = "animation_bad.gif")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment