How can I add a point in xy line in R? - 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)

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:

Calculate triangle areas - 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:

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:

R Programming: How to create a custom fit curve?

I'd like to create a graph that looks like this, but uses my own data for the min/max of the grey fit line
Here is a simple plot.
df <- data.frame(x1 = c(0,1,2,3,4),
y1 = c(2,3,4,5,6),
x2 = c(0,1,2,3,4),
y2 = c(3,4,6,7,8),
x3 = c(0,1,2,3,4),
y3 = c(0,0,1,2.5,2))
g <- ggplot(data=df) +
geom_line(aes(x1,y1,color="red")) +
geom_line(aes(x2,y2)) +
geom_line(aes(x3,y3))
I want a transparent grey fill area like in the example to be behind the red line and between the 2 black lines. How do I accomplish this?
You can use the polygon function for this.
x <- 1:50
y_low <- rnorm(length(x), 150, 25) + 5*x
y_high <- rnorm(length(x), 250, 25) + 5*x
plot(x, y_high, type='l', ylim = c(000, 600))
polygon(c(x, rev(x)), c(y_high, rev(y_low)), col = "grey40")
Another option (as mentioned in the comments) is to add the geom_ribbon attribute. You can specify customer values for the interval. The following did the work:
g <- ggplot(data=df) + geom_ribbon(aes(x=x1, ymin=y2, ymax=y3))
+ geom_line(aes(x1,y1,color="red"))
+ geom_line(aes(x2,y2)) + geom_line(aes(x3,y3))

Resources