Add straight line to a plot - r

How can I add a straight line form (5, 5) to infinity to this plot? I use abline but I do not want the line between 5 to 5, just I need after 5 to infinity.
x <- c(1:5); y <- x
plot(x, y, type="l")
abline(v= max(x), col="black", lwd=2, lty=2)

You can use segments and par('usr') to extract the existing axis limits. I've used lty=1 to show that it wil extend to the edge of the plotting area
plot(x,y,type = 'l')
segments(x0 = max(x), y0 = max(y), y1 = par('usr')[4], lwd=2)

Related

In R plotting line with different color above threshold limits

I have the following data and code in R:
x <- runif(1000, -9.99, 9.99)
mx <- mean(x)
stdevs_3 <- mx + c(-3, +3) * sd(x/5) # Statndard Deviation 3-sigma
And I plotted as line (alongwith 3 standard deviation and mean lines) in R:
plot(x, t="l", main="Plot of Data", ylab="X", xlab="")
abline(h=mx, col="red", lwd=2)
abline(h=stdevs_3, lwd=2, col="blue")
What I want to do:
Anywhere on the plot, whenever line is crossing 3 sigma thresholds (blue lines), above or below it, line should be in different color than black.
I tried this, but did not work:
plot(x, type="l", col= ifelse(x < stdevs_3[[1]],"red", "black"))
abline(h=mx, col="red", lwd=2)
abline(h=stdevs_3, lwd=2, col="blue")
Is there any other way?
This is what is requested, but it appears meaningless to me because of the arbitrary division of x by 5:
png( )
plot(NA, xlim=c(0,length(x)), ylim=range(x), main="Plot of Data", ylab="X", xlab="", )
stdevs_3 <- mx + c(-3, +3) * sd(x/5)
abline(h=mx, col="red", lwd=2)
abline(h=stdevs_3, lwd=2, col="blue")
segments( 0:999, head(x,-1), 1:1000, tail(x,-1) , col=c("black", "red")[
1+(abs(tail(x,-1)) > mx+3*sd(x/5))] )
dev.off()

How can I have the full range in the x- and y-axis labels in a plot?

I have two variables, x and y
x = runif(8, 0, runif(1, 1, 5))
y = x^2
that I want to plot. Note that the range of x (and hence y=x^2) is not always the same.
So, the command
plot(x, y, pch=19, col='red')
produces
However, I don't want the borders around the graph, so I use the bty='n' parameter for plot:
plot(x, y, pch=19, col='red', bty='n')
which produces
This is a bit unfortunate, imho, since I'd like the y-axis to go all the way up to 4 and the x-axis all the way to 2.
So, I ue the xaxp and yaxp parameters in the plot command:
plot(x, y, pch=19, col='red', bty='n',
xaxp=c(
floor (min(x)),
ceiling(max(x)),
5
),
yaxp=c(
floor (min(y)),
ceiling(max(y)),
5
)
)
which produces
This is a bit better, but it still doesn't show the full range. Also, I thought it nice that the default axis labaling uses steps that were like 1,2,3,4 or 0.5,1,1.5,2, not just some arbitrary fractions.
I guess R has some parameter or mechanism to plot the full range in the axis in a "humanly" fashion (0.5,1,1.5 ...) but I didn't find it. So, what could I try?
Try:
plot(x, y, pch=19, col='red', bty='n', xlim=c(min(x),max(x)),
ylim=c(min(y),max(y)), axes=FALSE)
axis(1, at=seq(floor(min(x)), ceiling(max(x)), 0.5))
axis(2, at=seq(floor(min(y)), ceiling(max(y)), 0.5))
Or if you'd prefer to hard-code those axis ranges:
axis(1, at=seq(0, 2, 0.5))
axis(2, at=seq(0, 4, 0.5))
Is that what you were after?

Icons as x-axis labels in R

I would like to plot something like this (from this paper) where icons, in this case small graphs, are used as tick labels.
I get this far, where icons are more or less properly placed:
This is the code:
library(igraph)
npoints <- 15
y <- rexp(npoints)
x <- seq(npoints)
par(fig=c(0.05,1,0.3,1), new=FALSE)
plot(y, xlab=NA, xaxt='n', pch=15, cex=2, col="red")
lines(y, col='red', lwd=2)
xspan <- 0.9
xoffset <- (0.07+0.5/npoints)*xspan
for(i in 1:npoints){
x1 <- (xoffset+(i-1)/npoints)*xspan
x2 <- min(xspan*(xoffset+(i)/npoints),1)
par(fig=c(x1,x2,0,0.5), new=TRUE)
plot(graph.ring(i), vertex.label=NA)
}
However, if the number of points grows (e.g. npoints <- 15) it complains because there is no place for the icons:
Error in plot.new() : figure margins too large
I wonder wether there is a more natural way to do this so that it works for any (reasonable) number of points.
Any advice is welcome.
library(igraph)
npoints <- 15
y <- rexp(npoints)
x <- seq(npoints)
# reserve some extra space on bottom margin (outer margin)
par(oma=c(3,0,0,0))
plot(y, xlab=NA, xaxt='n', pch=15, cex=2, col="red")
lines(y, col='red', lwd=2)
# graph numbers
x = 1:npoints
# add offset to first graph for centering
x[1] = x[1] + 0.4
x1 = grconvertX(x=x-0.4, from = 'user', to = 'ndc')
x2 = grconvertX(x=x+0.4, from = 'user', to = 'ndc')
# abline(v=1:npoints, xpd=NA)
for(i in x){
print(paste(i, x1[i], x2[i], sep='; '))
# remove plot margins (mar) around igraphs, so they appear bigger and
# `figure margins too large' error is avoided
par(fig=c(x1[i],x2[i],0,0.2), new=TRUE, mar=c(0,0,0,0))
plot(graph.ring(i), vertex.label=NA)
# uncomment to draw box around plot to verify proper alignment:
# box()
}

r xyplot "steps" centered on data points

the type argument to xyplot() can take "s" for "steps." From help(plot):
The two step types differ in their x-y preference: Going from
(x1,y1) to (x2,y2) with x1 < x2, 'type = "s"' moves first
horizontal, then vertical, whereas 'type = "S"' moves the other
way around.
i.e. if you use type="s", the horizontal part of the step has its left end attached to the data point, while type="S" has its right end attached to the data point.
library(lattice)
set.seed(12345)
num.points <- 10
my.df <- data.frame(x=sort(sample(1:100, num.points)),
y=sample(1:40, num.points, replace=TRUE))
xyplot(y~x, data=my.df, type=c("p","s"), col="blue", main='type="s"')
xyplot(y~x, data=my.df, type=c("p","S"), col="red", main='type="S"')
How could one achieve a "step" plot, where the vertical motion happens between data points points, i.e. at x1 + (x2-x1)/2, so that the horizontal part of the step is centered on the data point?
Edited to include some example code. better late than never I suppose.
I am using excellent #nico answer to give its lattice version. Even I am ok with #Dwin because the question don't supply a reproducible example, but customizing lattice panel is sometimes challenging.
The idea is to use panel.segments which is the equivalent of segments of base graphics.
library(lattice)
xyplot(y~x,
panel =function(...){
ll <- list(...)
x <- ll$x
y <- ll$y
x.start <- x - (c(0, diff(x)/2))
x.end <- x + (c(diff(x)/2, 0))
panel.segments(x.start, y, x.end, y, col="orange", lwd=2)
panel.segments(x.end[-length(x.end)], y[1:(length(y)-1)],
x.end[-length(x.end)], y[-1], col="orange", lwd=2)
## this is optional just to compare with type s
panel.xyplot(...,type='s')
## and type S
panel.xyplot(...,type='S')
})
This is a base graphics solution, as I am not too much of an expert in lattice.
Essentially you can use segments to draw first the horizontal, then the vertical steps, passing the shifted coordinates as a vector.
Here is an example:
set.seed(12345)
# Generate some data
num.points <- 10
x <- sort(sample(1:100, num.points))
y <- sample(1:40, num.points, replace=T)
# Plot the data with style = "s" and "S"
par(mfrow=c(1,3))
plot(x, y, "s", col="red", lwd=2, las=1,
main="Style: 's'", xlim=c(0, 100))
points(x, y, pch=19, col="red", cex=0.8)
plot(x, y, "S", col="blue", lwd=2, las=1,
main="Style: 'S'", xlim=c(0, 100))
points(x, y, pch=19, col="blue", cex=0.8)
# Now plot our points
plot(x, y, pch=19, col="orange", cex=0.8, las=1,
main="Centered steps", xlim=c(0, 100))
# Calculate the starting and ending points of the
# horizontal segments, by shifting the x coordinates
# by half the difference with the next point
# Note we leave the first and last point as starting and
# ending points
x.start <- x - (c(0, diff(x)/2))
x.end <- x + (c(diff(x)/2, 0))
# Now draw the horizontal segments
segments(x.start, y, x.end, y, col="orange", lwd=2)
# and the vertical ones (no need to draw the last one)
segments(x.end[-length(x.end)], y[1:(length(y)-1)],
x.end[-length(x.end)], y[-1], col="orange", lwd=2)
Here is the result:

How do I plot multiple probability distributions side-by-side in R?

I want to plot several probability distributions side-ways (density on the x-axis, variable on y-axis). Each distribution will be associated with a different category, and I want them side-by-side so that I can compare between them. This is a bit like a box-plot but instead I want an theoretical probability distribution that I will specify giving parameters. So if they were all normal distributions, I would simply provide the mean and std deviation for each. Thanks.
do you mean something like this?
x <- seq(-10, 10, length=100)
normal.dist <- dnorm(x, 0, 2)
f.dist <- df(x, 3, 4)
t.dist <- dt(x, 3)
chi.dist <- dchisq(x,3)
par(mfrow=c(2,2))
plot(x, normal.dist, type='l', lty=1 )
plot(x, f.dist, type='l', lty=1, xlab="x value", col='blue')
plot(x, t.dist, type='l', lty=1, xlab="x value", col='red')
plot(x, chi.dist, type='l', lty=1, xlab="x value", col='green')
see also Roman Luštrik's very helpful link as well as the helfiles (e.g. ?dnorm).
Rotated axis
x <- seq(-10, 10, length=100)
normal.dist <- dnorm(x, 0, 1)
normal.dist2 <- dnorm(x, 0, 2)
normal.dist3 <- dnorm(x, 0, 3)
normal.dist4 <- dnorm(x, 0, 4)
par(mfrow=c(2,2))
plot(normal.dist, x, type='l', lty=1 )
plot(normal.dist2, x, type='l', lty=1, col='red' )
plot(normal.dist3, x, type='l', lty=1, col='green' )
plot(normal.dist4, x, type='l', lty=1, col='blue' )
You can set up a frame for plot display and specify how many plots you want to show in a frame using par(mfrow()), for example:
par(mfrow=c(2,2))
plot(first plot)
plot(second plot)
hist(third histogram)
boxplot(fourth boxplot)
See the following link for the full description:
http://www.statmethods.net/advgraphs/layout.html

Resources