1

I am trying to plot a vector field, with some vectors set invisible, using this code:

library(cowplot)

size <- 1/12
strength <- 8
centerx <- 0
centery <- -12
diagsize <- 200

x <- rep(1:diagsize - diagsize/2, times = diagsize)
y <- rep(1:diagsize - diagsize/2, each = diagsize)
xend <- numeric()
yend <- numeric()
distance <- numeric()
replace_factor_01 <- numeric()
replace_factor <- numeric()
h <- numeric()

for (i in 1:(diagsize*diagsize)){ #
  distance[i] <- sqrt((x[i]-centerx)^2+(y[i]-centery)^2) # simply get absolute distance of each pixel to lens center
  replace_factor_01[i] <- 0 # this will be color intensity
  replace_factor[i] <- 0 # wheras this will be arrow length
  h[i] <- 0 # this will be color (0 = red, 0.667 = blue)
  if (distance[i] < 2*3.141592/size){replace_factor_01[i] <- sin(distance[i]*size)} # if within range, compute distortion as value -1..1
  replace_factor[i] <- replace_factor_01[i]*strength # linearly stretch
  if (replace_factor[i] < 0){h[i] <- 0.667} # set color
  xend[i] <- x[i] + (x[i]-centerx)/distance[i]*replace_factor[i] # compute distortion vector
  yend[i] <- y[i] + (y[i]-centery)/distance[i]*replace_factor[i]
  if ((x[i] %% 5) !=0 | (y[i] %% 5) != 0) {replace_factor_01[i] <- 0} # only set some arrows visible
}
data <- data.frame(x,y,distance, h, replace_factor_01,replace_factor,xend,yend)

p <- ggplot(data,aes(x,y))+
  geom_segment(aes(xend=xend,yend=yend),col=hsv(h,abs(replace_factor_01),1))
  #geom_segment(aes(xend=xend,yend=yend),col=hsv(h,abs(replace_factor_01),1), size=5)
print(p)

The result looks like this:

Vectorfield no size

When I use"size = 5", the lines don't merely become thicker, but look like this:

Vectorfield size 5

What am I getting wrong?

Axeman
  • 32,068
  • 8
  • 81
  • 94
MR13
  • 39
  • 4

1 Answers1

3

Your problem is that you're not actually making any segments "invisible", you're setting them to white. hsv(x,0,1) is always = #FFFFFF (white)

If we look at the graph with saturation fixed at 1, we can see the problem. A ton of segments are being colored white, making them overlap with the blue and red segments. When you increase size you exacerbate the problem.

p <- ggplot(data,aes(x,y))+
    geom_segment(aes(xend=xend,yend=yend),col=hsv(h,1,1))

enter image description here

I think what you really want to do is plot all the segments where replace_factor_01 is != 0. So we subset the data using data.table:

require(data.table)
setDT(data)
p <- ggplot(data[replace_factor_01 != 0],aes(x,y,color=distance))+
    geom_segment(aes(xend=xend,yend=yend),size=3)

enter image description here

And one final version to match your colors - I mapped replace_factor_01 to color (if you convert h to factor, you can use scale_color_manual() to get the two discrete colors like you defined in your plot):

p <- ggplot(data[replace_factor_01 != 0],aes(x,y))+
 geom_segment(aes(xend=xend,yend=yend,color=replace_factor_01),size=2)+
 scale_color_gradient(high="red",low="blue")+
 theme(legend.position="none")

enter image description here

Mako212
  • 6,787
  • 1
  • 18
  • 37
  • Thanks for that approach! Building on your hint that my above code didn't actually draw lines invisibly, I now found this alternative solution: `geom_segment(aes(xend=xend,yend=yend),col=hsv(h,1,1), alpha=abs(replace_factor_01), size = 3)` – MR13 Sep 18 '17 at 09:21