Rotate a plot (with below rotation setting) seems to be impossible in R according to Google.
So I am looking for a way to do that, but still no success till now.
Rotation setting :
The rotation center is the origin of plot ({0,0})
The given angle will be the angle between the y axis and the plot.
Here is a code where
a is something depending on angle and x axis length. (I think)
b is something depending on angle and y axis length. (I think)
:
speed <- cars$speed
dist <- cars$dist
plot(speed,dist, xlim=c(0,121), ylim=c(0,121))
xTemp <- speed
speed <- speed + (a)
dist <- dist + (b)
par(new=TRUE)
plot(speed,dist, xlim=c(0,121), ylim=c(0,121), col="red")
Any idea of a and b values ?
Here is for example a code in wich the plot is rotated by about 50 degrees from the y axis (Notice that is is not a true rotation. speed value is extended after rotation.. I don't now how to fix it.) :
speed <- cars$speed
dist <- cars$dist
plot(speed,dist, xlim=c(0,121), ylim=c(0,121))
xTemp <- speed
speed <- speed + dist
dist <- dist - xTemp
par(new=TRUE)
plot(speed,dist, xlim=c(0,121), ylim=c(0,121), col="red")
Just apply a rotation matrix
to your data.
angle <- pi/3
M <- matrix( c(cos(angle), -sin(angle), sin(angle), cos(angle)), 2, 2 )
plot( as.matrix(cars[,c("speed","dist")]) %*% M )
What happens may be clearer on a different example:
library(mlbench)
d <- mlbench.smiley()$x
op <- par(mfrow=c(1,2))
plot(d, asp=1)
plot(as.matrix(d) %*% M, col="red", asp=1)
par(op)
It looks I found the solution :
speed <- cars$speed
dist <- cars$dist
angle <- 45
plot(speed,dist, xlim=c(-121,121), ylim=c(-121,121))
speed1 <- double(); dist1=double()
for(i in 1:length(speed)){
sq <- sqrt((speed[i]*speed[i]) + (dist[i]*dist[i]))
angleInit <- (180*atan(dist[i]/speed[i]))/pi
angle2 <- angleInit - angle
speed1[i] <- cos(pi*angle2/180) * sq
dist1[i] <- sin(pi*angle2/180) * sq
}
par(new=TRUE)
plot(speed1,dist1, xlim=c(-121,121), ylim=c(-121,121), col="red")
Thank you
Related
I have made a ggplot using some A and B numeric values. (If possible can you give me the solution for grid too?)
Such as:
A B
2 3
3 7
4 8
5 9
6 2
7 1
Now from the points, lets say A1 and A2 as shown in diagram, I want to measure the angle and the distance covered from each point.
I know how to calculate the distance (via euclidean distance formula) from one point and for angle it can be calculated as cross and dot product of the vectors. But I am facing the problem to code this and to represent it.
Can you help?
Okay, here is a first pass - doing it in grid. This could be done in ggplot2 too I imagine, but I want to learn grid for now since ggplot2 and lattice are based on it. This plot has some issues, for example the angle of the annotation text really has to be calculated in device coordinates, not native coordinates, so it only looks right if your grid squares are really square. I might fix that later, but I don't have time now. Also I would think I could specify the defaults so that each primitive doesn't have that default.units parameter. This should get you started though.
library(grid)
grid.newpage()
df <- data.frame(a=c(2,3,4,5,6,7),b=c(3,7,8,9,2,1))
vp <- viewport(x=0.5,y=0.5,width=0.999,height=0.999,xscale=c(0,1),yscale=c(0,1))
pushViewport(vp)
# a rectangle (with dashed lines) on the border of the viewport:
grid.rect(gp=gpar(lty="dashed",col="steelblue"))
vp <- viewport(x=0.5,y=0.5,width=0.9,height=0.9,xscale=c(0,8),yscale=c(0,10),
default.units="native")
pushViewport(vp)
#draw the background grid
grid.polyline(x=rep(0:8,each=2),y=rep(c(0,10),9),id=rep(1:9,each=2),
gp=gpar(lty="solid",col="gray"),default.units="native")
grid.polyline(x=rep(c(0,8),11),y=rep(0:10,each=2),id=rep(1:11,each=2),
gp=gpar(lty="solid",col="gray"),default.units="native")
# add the lables
grid.text(as.character(0:8),x=0:8,y=rep(-0.2,9),
gp=gpar(col="gray",fontsize=12),default.units="native")
grid.text(as.character(0:10),y=0:10,x=rep(-0.2,11),
gp=gpar(col="gray",fontsize=12),default.units="native")
grid.lines(x=df$a,y=df$b,gp=gpar(col="steelblue"),default.units="native")
grid.points(x=df$a,y=df$b,gp=gpar(col="steelblue"),default.units="native")
for (i in 1:(nrow(df)-1)){
x0 <- df$a[i]
y0 <- df$b[i]
x1 <- df$a[i+1]
y1 <- df$b[i+1]
dx <- x1-x0
dy <- y1-y0
dist <- sqrt( dx^2 + dy^2 )
ang <- (180/3.14159)*atan2(dy,dx)
txt <- sprintf("D: %.1f Ang:%.1f",dist,ang)
xt <- (x0+x1)/2
yt <- (y0+y1)/2 + 0.2*abs(dy/dx)
grid.text(txt,x=xt,y=yt,rot=ang,
gp=gpar(col="steelblue",fontsize=9),default.units="native")
}
It sounds easier to calculate those angles and distances outside the plot,
library(dplyr)
d <- data.frame(x=c(2,3,4,5,6,7),
y=c(3,7,8,9,2,1))
d2 <- with(d, data.frame(dx=diff(x), dy=diff(y)))
d2 <- mutate(d2, distance = sqrt(dx^2 + dy^2),
angle = atan2(dy, dx))
ann <- mutate(cbind(d[-nrow(d),], d2),
x=x+dx/2, y=y+dy/2,
label = sprintf("%.2f\n %2.f degrees",
distance, angle*180/pi))
library(ggplot2)
ggplot(d, aes(x,y)) + geom_line() +
geom_text(data = ann, vjust = 0,
aes(x, y, label=label, angle=angle*180/pi)) +
coord_equal()
I have created a voronoi plot in R
gave the point labels
using the code:
install.packages("deldir")
library(deldir)
x <- runif(20); y <- runif(20); window <- c(0,1,0,1)
tess <- deldir(x, y, rw = window)
plot.deldir(tess, wpoints="real", wlines="tess")
label=c('a','b','c'.....'t')
library(plotrix)
thigmophobe.labels(x, y, labels=label)
can someone suggest a query so that,
if i give a location of a new point which is in the cell containing point 'a'
the output should be 'a'.
thanks in advance.
Since the voronoi tesselation is the boundary line between nearest points, your problem simply reduces to finding the nearest neighbour.
You can do this by computing a distance matrix using dist() and then extracting the point with minimum distance.
Try this:
library(deldir)
n <- 20
dat <- data.frame(
x = runif(n),
y =runif(n)
)
tess <- deldir(dat, rw = c(0,1,0,1))
plot.deldir(tess, wpoints="none", wlines="tess", col="blue")
label=letters[1:n]
text(dat, labels=label)
for (i in 1:500){
newdat <- data.frame(x=runif(1), y=runif(1))
np <- which.min(unname(as.matrix(dist(rbind(newdat, dat), diag=FALSE))[-1, 1]))
text(newdat, col="red", labels=label[np], cex=0.5)
}
You can use a point-location test:http://en.wikipedia.org/wiki/Point_location.
I am trying to visualise an upper triangular matrix that is approximately 500x500. Alongside this I am also trying to rotate that image so that it looks like the triangle is pointing upward:
(This was achieved by taking a snapshot of a graphics device and then rotating that image).
As in that image each column and row needs to have it's width specified.
I have tried using the image() function with the grid package (using a viewpanel that is rotated by 45 degrees) however that does not work. Does anybody know a better solution?
Here a simple and stupid approach using base graphics' rasterImage:
plotTriMatrix <- function(x) {
## clear lower triangle
x[lower.tri(x)] <- NA
## calculate diag
nr <- nrow(x)
nc <- ncol(x)
d <- sqrt(nr^2 + nc^2)
d2 <- 0.5 * d
## empty plot area
plot(NA, type="n", xlim=c(0, d), ylim=c(0, d), xlab="", ylab="", asp=1)
## plot matrix and rotate 45
rasterImage(as.raster(x),
xleft=d2, xright=d2+nc, ybottom=-d2, ytop=-d2+nr,
interpolate=FALSE, angle=45)
}
Example:
set.seed(123)
m <- matrix(runif(100), 10, 10)
plotTriMatrix(m)
I have a bunch of points that lie around y=x (see the examples below), and I hope to calculate the orthogonal distance of each point to this y=x. Suppose that a point has coordinates (a,b), then it's easy to see the projected point on the y=x has coordinates ((a+b)/2, (a+b)/2). I use the following native codes for the calculation, but I think I need a faster one without the for loops. Thank you very much!
set.seed(999)
n=50
typ.ord = seq(-2,3, length=n) # x-axis
#
good.ord = sort(c(rnorm(n/2, typ.ord[1:n/2]+1,0.1),rnorm(n/2,typ.ord[(n/2+1):n]-0.5,0.1)))
y.min = min(good.ord)
y.max = max(good.ord)
#
plot(typ.ord, good.ord, col="green", ylim=c(y.min, y.max))
abline(0,1, col="blue")
#
# a = typ.ord
# b = good.ord
cal.orth.dist = function(n, typ.ord, good.ord){
good.mid.pts = (typ.ord + good.ord)/2
orth.dist = numeric(n)
for (i in 1:n){
num.mat = rbind(rep(good.mid.pts[i],2), c(typ.ord[i], good.ord[i]))
orth.dist[i] = dist(num.mat)
}
return(orth.dist)
}
good.dist = cal.orth.dist(50, typ.ord, good.ord)
sum(good.dist)
As easy as
good.dist <- sqrt((good.ord - typ.ord)^2 / 2)
It all boils down to compute the distance between a point and a line. In the 2D case of y = x, this becomes particularly easy (try it yourself).
In the more general case (extending to other lines in possibly more than 2-D space), you can use the following. It works by constructing a projection matrix P from the subspace (here the vector A) onto which you want to project the points x. Subtracting the projected component from the points leaves the orthogonal component, for which it's easy to calculate the distances.
x <- cbind(typ.ord, good.ord) # Points to be projected
A <- c(1,1) # Subspace to project onto
P <- A %*% solve(t(A) %*% A) %*% t(A) # Projection matrix P_A = A (A^T A)^-1 A^T
dists <- sqrt(rowSums(x - x %*% P)^2) # Lengths of orthogonal residuals
Is there a way to draw a simple ellipse based on the following definition (instead of eigenvalue) in R?
The definition I want to use is that an ellipse is the set of points in a plane for which the sum of the distances to two fixed points F1 and F2 is a constant.
Should I just use a polar cordinate?
This may be more algorithmic question.
As #DWin suggested, there are several implementations for plotting ellipses (such as function draw.ellipse in package plotrix). To find them:
RSiteSearch("ellipse", restrict="functions")
That being said, implementing your own function is fairly simple if you know a little geometry. Here is an attempt:
ellipse <- function(xf1, yf1, xf2, yf2, k, new=TRUE,...){
# xf1 and yf1 are the coordinates of your focus F1
# xf2 and yf2 are the coordinates of your focus F2
# k is your constant (sum of distances to F1 and F2 of any points on the ellipse)
# new is a logical saying if the function needs to create a new plot or add an ellipse to an existing plot.
# ... is any arguments you can pass to functions plot or lines (col, lwd, lty, etc.)
t <- seq(0, 2*pi, by=pi/100) # Change the by parameters to change resolution
k/2 -> a # Major axis
xc <- (xf1+xf2)/2
yc <- (yf1+yf2)/2 # Coordinates of the center
dc <- sqrt((xf1-xf2)^2 + (yf1-yf2)^2)/2 # Distance of the foci to the center
b <- sqrt(a^2 - dc^2) # Minor axis
phi <- atan(abs(yf1-yf2)/abs(xf1-xf2)) # Angle between the major axis and the x-axis
xt <- xc + a*cos(t)*cos(phi) - b*sin(t)*sin(phi)
yt <- yc + a*cos(t)*sin(phi) + b*sin(t)*cos(phi)
if(new){ plot(xt,yt,type="l",...) }
if(!new){ lines(xt,yt,...) }
}
An example:
F1 <- c(2,3)
F2 <- c(1,2)
plot(rbind(F1, F2), xlim=c(-1,5), ylim=c(-1, 5), pch=19)
abline(h=0, v=0, col="grey90")
ellipse(F1[1], F1[2], F2[1], F2[2], k=2, new=FALSE, col="red", lwd=2)
points((F1[1]+F2[1])/2, (F1[2]+F2[2])/2, pch=3)