2
votes

I am trying to create a scatter plot in R where each point has either an arrow or just a line indicating an "orientation" or a direction associated with that specific point. Each point has a different orientation but all of the orientation lines should be the same length. The angles range from 0-360 degrees with 0 being rightwards and then moving counter clockwise from there. The biggest problem is that my axes are in log scale and the x and y axes increase at different rates which throws off the orientation. My data is a 3x35 matrix with X,Y coordinates and my orientation angle in the third column.

I have tried using the arrows function; however, the arrows don't seem to be pointing in the correct direction and their lengths vary based on the angle. Here is the simple code I used:

plot(data$SF.X., data$TF.Y.,log="xy", pch=19, cex=0.8,ylim=c(0.031,20), xlim = c(0.031,1))

arrows(data$SF.X., data$TF.Y., x1=data$SF.X.+length*cos(data$Degrees), y1=data$TF.Y.+length*sin(data$Degrees), 
       code = 2, length=0.03, col="Red")

This the result of the above code: enter image description here Can someone point me in the right direction as to how to get my orientation lines all the same length and pointing in the correct direction based on the angle value in my third column?

Thank you so much!

Here is a sample of my data set:

x = c(0.47,0.80,0.09,0.78,0.14)

y = c(2.71,4.51,1.85,5.56,0.98)

orientation (degrees) = c(42.51,9.27,11.31,0.52,93.4)
1
Could you share you data set? Also the scale of your x and y axes should be the same and you probably should not be using log scale. In fact for the rotation you must change your coordinate system. - saudic

1 Answers

0
votes

For the angles, it's easy, R always works with angles in radians so you just have to multiply your degrees vector by pi/180.

For the length of the arrows, it is much more tricky. There is a deformation due to axis scale and image format so I came up with a workaround by normalizing the axis, then changing the labels and saving the figure in a perfect square format. Probably not the best solution but it gives the expected output.

x = c(0.47,0.80,0.09,0.78,0.14)
y = c(2.71,4.51,1.85,5.56,0.98)
degrees = c(42.51,9.27,11.31,0.52,93.4)

x.norm = (x-min(x))/(max(x)-min(x))
y.norm = (y-min(y))/(max(y)-min(y))
l <- 0.15


png("/home/ubuntu/Downloads/sample.png", width=500, height=500)

par(mar=c(4,4,1,1))
plot(x.norm, y.norm, pch=19, cex=0.8, col="Blue", 
     axes=FALSE, xlab="x", ylab="y", xlim=c(-0.1,1.1), ylim=c(-0.1,1.1))
arrows(x.norm, y.norm, 
       x1=x.norm+l*cos(degrees*pi/180), y1=y.norm+l*sin(degrees*pi/180), 
       length=0.05, col="Gray")
axis(1, at=seq(0,1,0.1), round(seq(min(x),max(x), (max(x)-min(x))/10),1))
axis(2, at=seq(0,1,0.1), round(seq(min(y),max(y), (max(y)-min(y))/10),1))

dev.off()

enter image description here