Calculate triangle areas - R - r

I am trying to calculate triangle area of pair of running points (X1, Y1,…. Xn, Yn) with a fix point (Cx,Cy) but without success. Can someone tell me please what is the problem so I can try to solve it?
Script:
library(ggplot2)
nElem <- 100
xData <- as.data.frame(seq(1,nElem,5))
yData <- as.data.frame(seq(5,nElem,5))
xyDATA<- cbind(xData,yData)
colnames(xyDATA) <- c("xCoord","yCoord")
Cx <- 10
Cy <- 1
ggplot(xyDATA) + geom_point(aes(x = xCoord, y = yCoord)) + geom_point(aes(x = Cx, y = Cy),colour="red",size=4)
for(i in 1:19)
{
Ax <- xyDATA[i,1]
Ay <- xyDATA[i,2]
Bx <- xyDATA[i+1,1]
By <- xyDATA[i+1,2]
s <- abs(0.5*((Ax*(By-Cy))+(Bx*(Cy-Ay))+(Cx*(Ay-By))))
# print(Ax)
# print(Ay)
# print(Bx)
# print(By)
print(s)
}

If you don't see the point graph drawn then you should modify ggplot line like:
p <- ggplot(xyDATA) + geom_point(aes(x = xCoord, y = yCoord)) +
geom_point(aes(x = Cx, y = Cy),colour="red",size=4)
print(p)
The print() method for the graph object produces the actual display.
Now the image is shown as:

Related

How to set a logarithmic scale across multiple ggplot2 contour plots?

I am attempting to create three contour plots, each illustrating the following function applied to two input vectors and a fixed alpha:
alphas <- c(1, 5, 25)
x_vals <- seq(0, 25, length.out = 100)
y_vals <- seq(0, 50, length.out = 100)
my_function <- function(x, y, alpha) {
z <- (1 / (x + alpha)) * (1 / (y + alpha))
}
for each alpha in the vector alphas, I am creating a contour plot of z values—relative to the minimal z value—over x and y axes.
I do so with the following code (probably not best practices; I'm still learning the basics with R):
plots <- list()
for(i in seq_along(alphas)) {
z_table <- sapply(x_vals, my_function, y = y_vals, alpha = alphas[i])
x <- rep(x_vals, each = 100)
y <- rep(y_vals, 100)
z <- unlist(flatten(list(z_table)))
z_rel <- z / min(z)
d <- data.frame(cbind(x, y, z_rel))
plots[[i]] <- ggplot(data = d, aes(x = x, y = y, z = z_rel)) +
geom_contour_filled()
}
When alpha = 1:
When alpha = 25:
I want to display these plots in one grouping using ggarrange(), with one logarithmic color scale (as relative z varies so much from plot to plot). Is there a way to do this?
You can build a data frame with all the data for all alphas combined, with a column indicating the alpha, so you can facet your graph:
I basically removed the plot[[i]] part, and stacked up the d's created in the former loop:
d = numeric()
for(i in seq_along(alphas)) {
z_table <- sapply(x_vals, my_function, y = y_vals, alpha = alphas[i])
x <- rep(x_vals, each = 100)
y <- rep(y_vals, 100)
z <- unlist(flatten(list(z_table)))
z_rel <- z / min(z)
d <- rbind(d, cbind(x, y, z_rel))}
d = as.data.frame(d)
Then we create the alphas column:
d$alpha = factor(paste("alpha =", alphas[rep(1:3, each=nrow(d)/length(alphas))]),
levels = paste("alpha =", alphas[1:3]))
Then build the log scale inside the contour:
ggplot(data = d, aes(x = x, y = y, z = z_rel)) +
geom_contour_filled(breaks=round(exp(seq(log(1), log(1400), length = 14)),1)) +
facet_wrap(~alpha)
Output:

A ggplot2 equivalent of the lines() function in basic plot

For reasons I won't go into I need to plot a vertical normal curve on a blank ggplot2 graph. The following code gets it done as a series of points with x,y coordinates
dfBlank <- data.frame()
g <- ggplot(dfBlank) + xlim(0.58,1) + ylim(-0.2,113.2)
hdiLo <- 31.88
hdiHi <- 73.43
yComb <- seq(hdiLo, hdiHi, length = 75)
xVals <- 0.79 - (0.06*dnorm(yComb, 52.65, 10.67))/0.05
dfVertCurve <- data.frame(x = xVals, y = yComb)
g + geom_point(data = dfVertCurve, aes(x = x, y = y), size = 0.01)
The curve is clearly discernible but is a series of points. The lines() function in basic plot would turn these points into a smooth line.
Is there a ggplot2 equivalent?
I see two different ways to do it.
geom_segment
The first uses geom_segment to 'link' each point with its next one.
hdiLo <- 31.88
hdiHi <- 73.43
yComb <- seq(hdiLo, hdiHi, length = 75)
xVals <- 0.79 - (0.06*dnorm(yComb, 52.65, 10.67))/0.05
dfVertCurve <- data.frame(x = xVals, y = yComb)
library(ggplot2)
ggplot() +
xlim(0.58, 1) +
ylim(-0.2, 113.2) +
geom_segment(data = dfVertCurve, aes(x = x, xend = dplyr::lead(x), y = y, yend = dplyr::lead(y)), size = 0.01)
#> Warning: Removed 1 rows containing missing values (geom_segment).
As you can see it just link the points you created. The last point does not have a next one, so the last segment is removed (See the warning)
stat_function
The second one, which I think is better and more ggplotish, utilize stat_function().
library(ggplot2)
f = function(x) .79 - (.06 * dnorm(x, 52.65, 10.67)) / .05
hdiLo <- 31.88
hdiHi <- 73.43
yComb <- seq(hdiLo, hdiHi, length = 75)
ggplot() +
xlim(-0.2, 113.2) +
ylim(0.58, 1) +
stat_function(data = data.frame(yComb), fun = f) +
coord_flip()
This build a proper function (y = f(x)), plot it. Note that it is build on the X axis and then flipped. Because of this the xlim and ylim are inverted.

Boundaries with ggplot2

I have produced the following plot using ggplot2. As you see I have 3 different classes colored as red black blue. I would like plot two curves on the two boundary that separate red points from black point and blue points from black points. Any ideas I am completely lost.
My code is:
datax=data.frame(x=y_data,y=x_data,
Diff_Motif_XY=factor(diff_motif,levels=c(1,0,‌​-1)),
size=factor(abs(diff_motif)))
#
p=ggplot(datax,aes(x,y))+
geom_point(aes(colour = Diff_Motif_XY,size=size))+
xlab(cond2)+
ylab(cond1)+
scale_colour_manual(values=c("red","black","blue"))
I got (way too) curious. I think it looks like the boundary is a hyperbola. One could calculate the optimal bounding hyperbola using something like optim, but it would be a fair amount of work and it might not converge.
# Generate some data because the OP did not provide any
npts <- 30000
l_data <- pmax(0,runif(npts,-10,20))
s_data <- (20-l_data + 10)/6
xstar <- -5.1
ystar <- -5.1
x_data <- pmax(0,l_data + rnorm(npts,0,s_data)) + xstar
y_data <- pmax(0,l_data + rnorm(npts,0,s_data)) + ystar
ha <- 6.0
hb <- 6.0
xy2 <- ((x_data-xstar)/ha)^2 - ((y_data-ystar)/hb)^2 + 0.8*rnorm(npts)
diff_motif <- ifelse(xy2>1,1,ifelse(-xy2<1,0,-1))
cond1 <- ""
cond2 <- ""
# We need this to plot our hyperbola
genhyperbola <- function( cx,cy,a,b,u0,u1,nu,swap=F)
{
# Generate a hyperbola through the parametric representation
# which uses sinh and cosh
# We generate nu segements from u0 to u1
# swap just swaps the x and y axes allowing for a north-south hyperbola (swap=T)
#
# https://en.wikipedia.org/wiki/Hyperbola
#
u <- seq(u0,u1,length.out=nu)
x <- a*cosh(u)
y <- b*sinh(u)
df <- data.frame(x=x,y=y)
df$x <- df$x + cx
df$y <- df$y + cy
if (swap){
# for north-south hyperbolas
tmp <- df$x
df$x <- df$y
df$y <- tmp
}
return(df)
}
hyp1 <- genhyperbola(xstar,ystar, ha,hb, 0,2.2,100, swap=F)
hyp2 <- genhyperbola(xstar,ystar, ha,hb, 0,2.2,100, swap=T)
datax=data.frame(x=x_data,y=y_data,
Diff_Motif_XY=factor(diff_motif,levels=c(1,0,-1)),
size=0)
eqlab1 <- sprintf("((x+%.1f)/%.1f)^{2}-((y+%.1f)/%.1f)^{2} == 1",xstar,ha,ystar,hb)
eqlab2 <- sprintf("((y+%.1f)/%.1f)^{2}-((x+%.1f)/%.1f)^{2} == 1",ystar,hb,xstar,ha)
#
p=ggplot(datax,aes(x,y))+
geom_point(aes(colour = Diff_Motif_XY),shape=".")+
geom_path(data=hyp1,aes(x,y),color=I("purple"),size=1)+
geom_path(data=hyp2,aes(x,y),color=I("brown"),size=1)+
xlab(cond2)+
ylab(cond1)+
scale_colour_manual(values=c("blue","black","red")) +
annotate('text', x=xstar+20, y=ystar+2,
label = eqlab1,parse = TRUE,size=6,color="purple") +
annotate('text', x=xstar+5, y=ystar+20,
label = eqlab2,parse = TRUE,size=6,color="brown")
print(p)
And here is the image:

How can I add a point in xy line in R?

I have a line chart with 2 lines. But I want to show the point where two lines are overlapping. It will be nicer if I show the point with lines additionally.
Q<-8
xdata <- seq(1,Q*2,1)
HCdata <- matrix(1,1)
OCdata <- matrix(1,1)
for (i in xdata) {
OC<-(100/i)*100
HC<-(i/2)*20*20
HCdata[i]<- HC
OCdata[i]<- OC
}
holdingcost <- data.frame(holdingcost=HCdata)
orderingcost <- data.frame(orderingcost=OCdata)
xx<-cbind(holdingcost,orderingcost)
y <- ggplot(xx, aes(xdata))
y1 <- y + geom_line(size=1,aes(y=holdingcost, colour = "holdingcost"))
y1 <- y1 + geom_line(size=1,aes(y=orderingcost, colour = "orderingcost"))
Find the x value where they are closest to equal:
eq <- xx[which.min(abs(xx$holdingcost - xx$orderingcost)), ]
Add the point:
y1 + geom_point(data = eq, aes(y = holdingcost), size = 2)

How to plot the intersection of a hyperplane and a plane in R

I have a set of (2-dimensional) data points that I run through a classifier that uses higher order polynomial transformations. I want to visualize the results as a 2 dimensional scatterplot of the points with the classifier superimbosed on top, preferably using ggplot2 as all other visualizations are made by this. Pretty much like this one that was used in the ClatechX online course on machine learning (the background color is optional).
I can display the points with colors and symbols and all, that's easy but I can't figure out how to draw anything like the classifiers (the intersection of the classifiing hyperplane with the plane representing my threshold). The only thing I found was stat_function and that only takes a function with a single argument.
Edit:
The example that was asked for in the comments:
sample data:
"","x","y","x","x","y","value"
"1",4.17338115745224,0.303530843229964,1.26674990184152,17.4171102853774,0.0921309727918932,-1
"2",4.85514814266935,3.452660451876,16.7631779801937,23.5724634872656,11.9208641959486,1
"3",3.51938610081561,3.41200957307592,12.0081790673332,12.3860785266141,11.6418093267617,1
"4",3.18545089452527,0.933340128976852,2.97310914874565,10.1470974014319,0.87112379635852,-16
"5",2.77556006214581,2.49701633118093,6.93061880335166,7.70373365857888,6.23509055818427,-1
"6",2.45974169578403,4.56341833807528,11.2248303614692,6.05032920997851,20.8247869282818,1
"7",2.73947941488586,3.35344674880616,9.18669833727041,7.50474746458339,11.2456050970786,-1
"8",2.01721803518012,3.55453519499861,7.17027250203368,4.06916860145595,12.6347204524838,-1
"9",3.52376445778646,1.47073399974033,5.1825201951431,12.4169159539591,2.1630584979922,-1
"10",3.77387718763202,0.509284208528697,1.92197605658768,14.2421490273294,0.259370405056702,-1
"11",4.15821685106494,1.03675272315741,4.31104264382058,17.2907673804804,1.0748562089743,-1
"12",2.57985028671101,3.88512040604837,10.0230289934507,6.65562750184287,15.0941605694935,1
"13",3.99800728890114,2.39457673509605,9.5735352407471,15.9840622821066,5.73399774026327,1
"14",2.10979392635636,4.58358959294856,9.67042948411309,4.45123041169019,21.0092935565863,1
"15",2.26988795562647,2.96687697409652,6.73447830932721,5.15239133109813,8.80235897942413,-1
"16",1.11802248633467,0.114183261757717,0.127659454208164,1.24997427994995,0.0130378172656312,-1
"17",0.310411276295781,2.09426849964075,0.650084557879535,0.0963551604515758,4.38596054858751,-1
"18",1.93197490065359,1.72926536411978,3.340897280049,3.73252701675543,2.99035869954433,-1
"19",3.45879891654477,1.13636834081262,3.93046958599847,11.9632899450912,1.29133300600123,-1
"20",0.310697768582031,0.730971727753058,0.227111284709427,0.0965331034018534,0.534319666774291,-1
"21",3.88408110360615,0.915658151498064,3.55649052359657,15.0860860193904,0.838429850404852,-1
"22",0.287852146429941,2.16121324687265,0.622109872005114,0.0828588582043242,4.67084269845782,-1
"23",2.80277011333965,1.22467750683427,3.4324895146344,7.85552030822994,1.4998349957458,-1
"24",0.579150241101161,0.57801398797892,0.334756940497835,0.335415001767533,0.334100170299295-,1
"25",2.37193428212777,1.58276639413089,3.7542178708388,5.62607223873297,2.50514945839009,-1
"26",0.372461311053485,2.51207412336953,0.935650421453748,0.138727428231681,6.31051640130279,-1
"27",3.56567220995203,1.03982002707198,3.70765737388213,12.7140183088242,1.08122568869998,-1
"28",0.634770628530532,2.26303249713965,1.43650656059435,0.402933750845047,5.12131608311011,-1
"29",2.43812176748179,1.91849716124125,4.67752968967431,5.94443775306852,3.68063135769073,-1
"30",1.08741064323112,3.01656032912433,3.28023980783858,1.18246190701233,9.0996362192467,-1
"31",0.98,2.74,2.6852,0.9604,7.5076,1
"32",3.16,1.78,5.6248,9.9856,3.1684,1
"33",4.26,4.28,18.2328,18.1476,18.3184,-1
The code to generate a classifier:
perceptron_train <- function(data, maxIter=10000) {
set.seed(839)
X <- as.matrix(data[1:5])
Y <- data["value"]
d <- dim(X)
X <- cbind(rep(1, d[1]), X)
W <- rep(0, d[2] + 1)
count <- 0
while (count < maxIter){
H <- sign(X %*% W)
indexs <- which(H != Y)
if (length(indexs) == 0){
break
} else {
i <- sample(indexs, 1)
W <- W + 0.1 * (X[i,] * Y[i,])
}
count <- count + 1
point <- as.data.frame(data[i,])
plot_it(data, point, W, paste("plot", sprintf("%05d", count), ".png", sep=""))
}
W
}
The code to generate the plot:
plot_it <- function(data, point, weights, name = "plot.png") {
line <- weights_to_line(weights)
point <- point
png(name)
p = ggplot() + geom_point(data = data, aes(x, y, color = value, size = 2)) + theme(legend.position = "none")
p = p + geom_abline(intercept = line[2], slope = line[1])
print(p)
dev.off()
}
This was solved using material from the question and answers from Issues plotting a fitted SVM model's decision boundary using ggplot2's stat_contour(). I skipped the call to geom_point for the grid-entires and some of the aesthetical definitions like scale_fill_manual and scale_colour_manual. Removing the dots for the grid entries solved the problem with the vanishing contour-line in my case.
train_and_plot_svm <- function(train, kernel = "sigmoid", type ="C", cost, gamma) {
fit <- svm(as.factor(value) ~ x + y, data = train, kernel = kernel, type = type, cost = cost)
grid <- expand.grid (x = seq(from = -0.1, to = 15, length = 100), y = seq(from = -0.1, to = 15, length = 100))
decisionValues <- as.vector(attributes(predict(fit, grid, decision.values = TRUE))$decision)
p <- predict(fit, grid)
grid$value <- p
grid$z <- decisionValues
p <- ggplot() + stat_contour(data = grid, aes(x = x, y = y, z = z), breaks = c(0))
p <- p + geom_point(data = train, aes(x, y, colour = as.factor(value)), alpha = 0.7)
p <- p + xlim(0,15) + ylim(0,15) + theme(legend.position="none")
}
Note that this function doesn't return the result of the svm training but the ggplot2 object.
This is, what I got:

Resources