R: polygon does not align with curves - r

I made the plot below in R. The edges of the polygon should align with the two curves as they are plotted using the same vectors. Yet, the polygon is slightly higher on the Y-axis relative to the curves. I cannot figure out why.
How do I get the outer edges of the polygon to align with the two curves?
Similarly, why does the polygon not extend all the way too the right end of the two curves? The curves are somewhat loner than the polygon.
I realize that I can plot the polygon with borders and not plot the two lines. That does not solve the underlying problem. Both the polygon and the two curves are plotted using the upper and lower vectors so I think they should align exactly. They do not.
lower <- qchisq(0.05,0:100)
upper <- qchisq(0.95,0:100)
df <- (0:100)
plot(df,upper, type='n', axes=F)
polygon(c(0,df,rev(df)), c(0,upper,rev(lower)), col='grey75',border=NA)
axis(1,pos=0)
axis(2,pos=0, las=1)
lines(upper, col='black')
lines(lower,col='black')

lines assumes the index is 1:length(x) (where x is the input) when you don't specify a second argument.
But in your case it's 0:100. Add df as the first argument to lines:
lines(df, upper, col='black')
lines(df, lower, col='black')

Related

How to add orientation (direction/angle/azimuth) to all points in scatterplot?

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:
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)
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()

How to rotate 180 degrees an mtext() in R

Apparently, mtext() in R doesn't support the srt parameter whose job is to rotate a piece of text.
I need mtext() to create an axis title on side 4 of my moving plot (i.e., values to be plotted come from a function so they change and so do the plot axes values). I was wondering then, what options do I have to rotate 180 degrees this side 4 axis title?
An example is BELOW:
curve(dnorm(x),-3,3)
mtext("Strength",side=4,srt=180)
You can use par("usr") to obtain extremes of the plot area and use it to place your text without having to explicitly specify the x and y.
Try
curve(dnorm(x),-3,3)
corners = par("usr") #Gets the four corners of plot area (x1, x2, y1, y2)
par(xpd = TRUE) #Draw outside plot area
text(x = corners[2]+.5, y = mean(corners[3:4]), "Strength", srt = 270)
This way it will always be on the right extreme and vertically in the middle.

Plotting ellipsoids / oblate spheroids in rgl

I have been using rgl to plot spheres, but now I need to plot ellipsoids.
The package includes ellipse3d; however, this seems to be for fitting ellipsoids to data, using matrices and stuff I'm not very good at.
What I want is a simple way to plot ellipsoids, in a similar way to spheres, using the centre coordinates and the scales in each direction. Can anyone help me out?
If you don't need the ellipse rotated around the axes, then you can just use a diagonal matrix for x (this plots a sphere, and defines the virtual "axes" along the x, y, z axes) and use the centre and scale parameters to shift the location and change the proportions.
plot3d(ellipse3d(diag(3),centre=c(1,2,4),scale=c(1,2,5)))
There's one in my cda package,
library(cda)
library(rgl)
## single ellipsoid
plot3d(rgl.ellipsoid(a=2,b=1,c=5))
## multiple ellipsoids, translated and rotated
cl <- helix(0.5, 1, 36, delta=pi/6, n.smooth=1e3)
sizes <- equal_sizes(0.04,0.02,0.02,NROW(cl$positions))
rgl.ellipsoids(cl$positions, sizes, cl$angles, col="gold")

Contour plot with 90 degree angles

I have a matrix, say cmat <- matrix(c(0,0,1,0,1,1,0,1,1),3,3) and I would like to plot the exact contours of the "region" with containing ones.
When using a contourplot(cmat) what I get is lines that define a sort of "smoothed" contour rather than following exactly the tiles. What I would like is a graph made only out of vertical and horizontal lines.
Does anyone know a function performing that?
Thanks in advance,
Renzu

Calculate area from Lat/Lon matrix or within a 50% contour for multiple polygons in R

I want to find the total area from multiple polygons within different contour lines from kernel densities (kde2d).
Here is an image of the kernel density and the 50% contour line. How do I calculate the area within the 50% contour line?
I also created a matrix of lat lon coordinates, which represents the points within this 50% contour line. Would it be easier to calculate the total area using these points.
Any suggestions would be greatly appreciated!
Once you have your coordinates in a cartesian system, and have done the kernel smoothing using those coordinates, you can use the contourLines function to get the coordinates of the lines, and then the areapl function from the splancs package to compute the area of each simple ring.
For example, using the example in help(kde2d):
attach(geyser)
plot(duration, waiting, xlim = c(0.5,6), ylim = c(40,100))
f1 <- kde2d(duration, waiting, n = 50, lims = c(0.5, 6, 40, 100))
image(f1)
contour(f1)
so that's our data set up - suppose we want the area in the 0.008 contour:
C8 = contourLines(f1,level=0.008)
length(C8)
[1] 3
Now C8 is a list of length 3. We need to apply the areapl function over each of these:
> sapply(C8,function(ring){areapl(cbind(ring$x,ring$y))})
[1] 14.65282 12.27329 14.75005
And we can obviously sum:
> sum(sapply(C8,function(ring){areapl(cbind(ring$x,ring$y))}))
[1] 41.67617
Now this only makes sense if the coordinates are cartesian, and if the contour lines are complete loops. If the 0.008 contour was near the edge then its possible for the contour to get clipped to the bounding box and then bad things happen. Check at least that the last point of each ring is the same as the first.

Resources