Визуализация векторного поля R
У меня есть большой текстовый файл с большим количеством строк. Каждой строке соответствует один вектор.
Это пример каждой строки:
x y dx dy
99.421875 52.078125 0.653356799108 0.782479314511
Первые два столбца являются координатами начала вектора. И два вторых столбца - это координаты (конец минус начало).
Мне нужно сделать изображение этого векторного поля (все векторы на одном изображении).
Как я могу это сделать?
Спасибо вам
Ответы
Ответ 1
С помощью ggplot2
вы можете сделать что-то вроде этого:
library(grid)
df <- data.frame(x=runif(10),y=runif(10),dx=rnorm(10),dy=rnorm(10))
ggplot(data=df, aes(x=x, y=y)) + geom_segment(aes(xend=x+dx, yend=y+dy), arrow = arrow(length = unit(0.3,"cm")))
![enter image description here]()
Это берется почти непосредственно с справочной страницы geom_segment
.
Ответ 2
Если есть много данных (вопрос говорит "большой файл" )
построение отдельных векторов может не дать очень читаемого сюжета.
Вот еще один подход: векторное поле описывает способ деформирования чего-то, нарисованного на плоскости;
примените его к изображению белого шума.
vector_field <- function(
f, # Function describing the vector field
xmin=0, xmax=1, ymin=0, ymax=1,
width=600, height=600,
iterations=50,
epsilon=.01,
trace=TRUE
) {
z <- matrix(runif(width*height),nr=height)
i_to_x <- function(i) xmin + i / width * (xmax - xmin)
j_to_y <- function(j) ymin + j / height * (ymax - ymin)
x_to_i <- function(x) pmin( width, pmax( 1, floor( (x-xmin)/(xmax-xmin) * width ) ) )
y_to_j <- function(y) pmin( height, pmax( 1, floor( (y-ymin)/(ymax-ymin) * height ) ) )
i <- col(z)
j <- row(z)
x <- i_to_x(i)
y <- j_to_y(j)
res <- z
for(k in 1:iterations) {
v <- matrix( f(x, y), nc=2 )
x <- x+.01*v[,1]
y <- y+.01*v[,2]
i <- x_to_i(x)
j <- y_to_j(y)
res <- res + z[cbind(i,j)]
if(trace) {
cat(k, "/", iterations, "\n", sep="")
dev.hold()
image(res)
dev.flush()
}
}
if(trace) {
dev.hold()
image(res>quantile(res,.6), col=0:1)
dev.flush()
}
res
}
# Sample data
van_der_Pol <- function(x,y, mu=1) c(y, mu * ( 1 - x^2 ) * y - x )
res <- vector_field(
van_der_Pol,
xmin=-3, xmax=3, ymin=-3, ymax=3,
width=800, height=800,
iterations=50,
epsilon=.01
)
image(-res)
![Van der Pol attractor]()
Вы можете применить некоторую обработку изображения к результату, чтобы сделать его более читаемым.
image(res > quantile(res,.6), col=0:1)
![After thresholding]()
В вашем случае векторное поле не описывается функцией:
вы можете использовать значение ближайшего соседа или некоторую двумерную интерполяцию
(например, из пакета akima
).
Ответ 3
ОК, здесь базовое решение:
DF <- data.frame(x=rnorm(10),y=rnorm(10),dx=runif(10),dy=runif(10))
plot(NULL, type = "n", xlim=c(-3,3),ylim=c(-3,3))
arrows(DF[,1], DF[,2], DF[,1] + DF[,3], DF[,2] + DF[,4])
Ответ 4
Вот пример из R-справки pracma-пакета.
library(pracma)
f <- function(x, y) x^2 - y^2
xx <- c(-1, 1); yy <- c(-1, 1)
vectorfield(f, xx, yy, scale = 0.1)
for (xs in seq(-1, 1, by = 0.25)) {
sol <- rk4(f, -1, 1, xs, 100)
lines(sol$x, sol$y, col="darkgreen")
}
Вы также можете использовать колчан.
library(pracma)
xyRange <- seq(-1*pi,1*pi,0.2)
temp <- meshgrid(xyRange,xyRange)
u <- sin(temp$Y)
v <- cos(temp$X)
plot(range(xyRange),range(xyRange),type="n",xlab=expression(frac(d*Phi,dx)),ylab=expression(d*Phi/dy))
quiver(temp$X,temp$Y,u,v,scale=0.5,length=0.05,angle=1)