Matching an arrow's ends with the x-axis R plot - r

I'm wondering how to to get the left-most end and the right-most end of my arrows() in my plot to EXACTLY match the left-most end and the right-most end of my X-AXIS lying beneath it (if possible, such that one can read the values (within rounding error) for two ends of the arrow off the X-Axis right below it)?
Here is my R code with no success:
ci <- c(0.09253967, 0.48434172)
plot(1, 1, ty="n" ,ann=F, yaxt="n", bty="n", xlim=c(ci[1], ci[2]), ylim=c(0, 1), xaxs="i")
arrows(ci[1], .01, ci[2], .01, code=3, lwd=2, angle = 90, length = .08 )

One method: control where axis places the ticks:
ci <- c(0.09253967, 0.48434172)
plot(1, 1, ty="n" ,ann=F, yaxt="n", bty="n", xlim=c(ci[1], ci[2]), ylim=c(0, .3), xaxt="n")
axis(side = 1, at = ci)
arrows(ci[1], .01, ci[2], .01, code=3, lwd=2, angle = 90, length = .08 )
... but the ticks are at not-pretty locations (though you can easily control this).
Another method: find what axTicks thinks would be the correct axis ticks for the current plot:
newx <- range(axTicks(side = 1))
newx
# [1] 0.1 0.4
# ... your plotting code ...
arrows(newx[1], 0.02, newx[2], 0.02, code=3, lwd=2, angle=90, length=.08)

Related

How to find y value in line-and-dots plot?

I have this line-and-dots plot:
#generate fake data
xLab <- seq(0, 50, by=5);
yLab <- c(0, sort(runif(10, 0, 1)));
#this value is fixed
fixedVal <- 27.3
#new window
dev.new();
#generate the plot
paste0(plot(xLab, yLab, col=rgb(50/255, 205/255, 50/255, 1), type="o", lwd=3,
main="a line-and-dots plot", xlab="some values", ylab="a percentage",
pch=20, xlim=c(0, 50), ylim=c(0, 1), xaxt="n", cex.lab=1.5, cex.axis=1.5,
cex.main=1.5, cex.sub=1.5));
#set axis
axis(side = 1, at=c(seq(min(xLab), max(xLab), by=5)))
#plot line
abline(v=fixedVal, col="firebrick", lwd=3, lty=1);
now, I would like to find the y coordinate of the intersection point between the green and the red lines.
Can I achieve the goal without the need of a regression line? Is there a simple way of getting the coordinates of that unknown point?
You can use approxfun to do the interpolation:
> approxfun(xLab,yLab)(fixedVal)
[1] 0.3924427
Alternatively, just use approx:
> approx(xLab,yLab,fixedVal)
$x
[1] 27.3
$y
[1] 0.3924427
Quick fix like #JohnColeman said:
# find the two points flanking your value
idx <- findInterval(fixedVal,xLab)
# calculate the deltas
y_delta <- diff(yLab[idx:(idx+1)])
x_delta <- diff(xLab[idx:(idx+1)])
# interpolate...
ycut = (y_delta/x_delta) * (fixedVal-xLab[idx]) + yLab[idx]
ycut
[1] 0.4046399
So we try it on the plot..
paste0(plot(xLab, yLab, col=rgb(50/255, 205/255, 50/255, 1), type="o", lwd=3,
main="a line-and-dots plot", xlab="some values", ylab="a percentage",
pch=20, xlim=c(0, 50), ylim=c(0, 1), xaxt="n", cex.lab=1.5, cex.axis=1.5,
cex.main=1.5, cex.sub=1.5));
#set axis
axis(side = 1, at=c(seq(min(xLab), max(xLab), by=5)))
#plot line
abline(v=fixedVal, col="firebrick", lwd=3, lty=1);
abline(h=ycut, col="lightblue", lwd=3, lty=1);

How to keep the space between tick and label minimum?

i've got a tiny problem in here, which i would like to have some hints on.
How can i change the space between ticks and labels? (indicated with 1 & 2)
my current structure looks as follows:
par(mfrow=c(5,2),oma=c(0,0,2,0),las=1,mar=c(3,5,2,1),cex.lab=0.9, cex.axis=0.7)
plot(sapply(ERRORS.train.fast[[1]],mean),main="Pipe 63569",type="l", ylab="", xlab="",xaxt="n")
axis(1, at=1:29,labels=seq(2,30,1))
title(ylab= "RMSE (-)",line=3)
title(xlab= "K-Value",line=2)
highly appreciate your help!
cheers,
Olli
You can use the padj argument for "adjustment for each tick label perpendicular to the reading direction." (from ?axis)
par(mfrow = c(1, 2))
plot(1:5, axes = F)
axis(1)
plot(1:5, axes = F)
axis(1, padj = -.75)
Unfortunately, the directions are different for the different axes (because it is relative what is "up" for the text), so to move the labels closer to the ticks, you will want lower padj values for the horizontal axis, but higher padj values for the vertical axis.
If you rotate the labels (as shown in your example plot on the vertical axis), you will use hadj instead of padj. Overall, I would expect you want something like:
plot(1:5, axes = F)
axis(1, padj = -.75)
axis(2, hadj = 0, las = 1)
You can use the mpg par.
par(mfrow=c(1,2))
plot(iris[,3:4], pch=20, col=rainbow(3)[iris$Species],
ylab="", xlab="",xaxt="n")
axis(1, at=1:7)
plot(iris[,3:4], pch=20, col=rainbow(3)[iris$Species],
ylab="", xlab="", xaxt="n")
axis(1, at=1:7, mgp=c(0,0.5,0))

R- Break axis matplot function

I need to break an axis from 0.5 to 1.5. My code is:
matplot( wxyz$days_until_last_pay, wxyz[,c(2,3,4,5)], type=c("b"), pch=1, col=1:4,
main="x![enter image description here][1]", cex.main=0.8)
legend("bottomright", inset=c(0,-0.57), fill=NULL,
legend = c("mean","median","max", "min"), col=1:4, pch=1, cex=0.8)
library("plotrix")
axis.break(axis=2,1,,2,style="zigzag", brw=0.03)
But I only get a line in it. This is not breaking the axis.
How can I solve this?
Thanks!
axis.break puts a break into an existing plot, so if the axis is not "broken" it will not work.
One suggestion is to make two plots on top of each other and set their ylim be so that there is a gap between 0.5 and 1.5, e.g.
## Some data, set.seed(1)
dat <- matrix(c(rnorm(50, 2, 0.1),
rnorm(50, 0.2, 0.05),
rnorm(50, 0.3, 0.05)),
byrow=FALSE, ncol=3)
## Split the device into two subplots
par(mfrow = c(2,1))
## Set the bottom margin of the top plot to 0.1
par(mar=c(0.1,4.1,4.1,2))
## Top plot (first column of the matrix)
plot(dat[,1], add=T, type="l", xaxt="n", ylab="", ylim=c(1.5, 2.5))
## Set the top margin of the bottom plot to 0.1
par(mar=c(5.1,4.1,0.1,2))
## Bottom plot
matplot(dat[,2:3], type="l", col=2:3, ylab="", ylim=c(0, 0.5))
This gives you something like:

Change the number of tick marks on a figure in R

I created a figure of two plots (two years) of climate data (temp and precip) that looks exactly like I want it, except that one of my axes has too many tick marks. With everything I have going on with this figure, I can't find a way to specify fewer tick marks without messing up other parts. I would also like to specify where the tick marks are. Here is the figure:
You can see that the tick marks for the top axis just blur together and the numbers chosen are not very meaningful to me. How can I tell R what I really want?
Here are the datasets I am using: cobs10 and
cobs11.
And here is my code:
par(mfrow=c(2,1))
par(mar = c(5,4,4,4) + 0.3)
plot(cobs10$day, cobs10$temp, type="l", col="red", yaxt="n", xlab="", ylab="",
ylim=c(-25, 30))
axis(side=3, col="black", at=cobs10$day, labels=cobs10$gdd)
at = axTicks(3)
mtext("Thermal Units", side=3, las=0, line = 3)
axis(side=2, col='red', labels=FALSE)
at= axTicks(2)
mtext(side=2, text= at, at = at, col = "red", line = 1, las=0)
mtext("Temperature (C)", side=2, las=0, line=3)
par(new=TRUE)
plot(cobs10$gdd, cobs10$precip, type="h", col="blue", yaxt="n", xaxt="n", ylab="",
xlab="")
axis(side=4, col='blue', labels=FALSE)
at = axTicks(4)
mtext(side = 4, text = at, at = at, col = "blue", line = 1,las=0)
mtext("Precipitation (cm)", side=4, las=0, line = 3)
par(mar = c(5,4,4,4) + 0.3)
plot(cobs11$day, cobs11$temp, type="l", col="red", yaxt="n", xlab="Day of Year",
ylab="", ylim=c(-25, 30))
axis(side=3, col="black", at=cobs11$day, labels=cobs11$gdd)
at = axTicks(3)
mtext("", side=3, las=0, line = 3)
axis(side=2, col='red', labels=FALSE)
at= axTicks(2)
mtext(side=2, text= at, at = at, col = "red", line = 1, las=0)
mtext("Temperature (C)", side=2, las=0, line=3)
par(new=TRUE)
plot(cobs11$gdd, cobs11$precip, type="h", col="blue", yaxt="n", xaxt="n", ylab="",
xlab="", ylim=c(0,12))
axis(side=4, col='blue', labels=FALSE)
at = axTicks(4)
mtext(side = 4, text = at, at = at, col = "blue", line = 1,las=0)
mtext("Precipitation (cm)", side=4, las=0, line = 3)
Thanks for thinking about it.
You've pretty much got the solution already:
axis(side=3, col="black", at=cobs10$day, labels=cobs10$gdd)
Except, you are asking to have ticks and labels at every single entry.
Take a look at the function pretty:
at <- pretty(cobs10$day)
at
# [1] 0 100 200 300 400
These are where the ticks should be placed on the x-axis. Now you need to find the corresponding labels. This is not straigtforward, but we will get:
lbl <- which(cobs10$day %in% at)
lbl
# [1] 100 200 300
lbl <- c(0, cobs10$gdd[lbl]
axis(side=3, at=at[-5], labels=lbl)
Update
I've been a bit annoyed by your use of three different series in a single plot. There are many reasons this is troublesome.
Having two y-values are always troublesome see this article from Stephen Few (go to page 5 for my favorite example); in your case it is not that serious due to the nature of the plots and your use of colours to indicate which y-axis the values belong to. But still, on principle.
Axis ticks should have a fixed function, e.g. linear or logarithm. With your Thermal Units, they appear "randomly" (I know that is not the case, but for an outsider they do).
We gotta do something about your x-axis ticks that just refer to "day of year".
First up, we take a look at your data and see what can be done naively. We recognize that your ''date'' variable is actual dates. Let's exploit it and make R aware of it!
cobs10 <- read.table('cobs10.txt',as.is=TRUE)
cobs10$date <- as.Date(cobs10$date)
plot(temp ~ date, data=cobs10, type='l')
Here, I really like the x-axis ticks and had some trouble replicating it. ''pretty'' on dates insisted on either 4 ticks or 12 ticks. But we will come back to that later.
Next, we can do something about the overlay plotting. Here I use ''par(mfrow=c(3,1))'' to instruct R to have three multiple plots stacked in a single window; with these multiple plots we can differentiate between inner and outer margins. The ''mar'' and ''oma'' arguments refers to the inner and outer margin.
Lets put all three variable together!
par(mfrow=c(3,1), mar=c(0.6, 5.1, 0, 0.6), oma=c(5.1, 0, 1, 0))
plot(temp ~ date, data=cobs10, type='l', ylab='Temperatur (C)')
plot(precip ~ date, data=cobs10, type='l', ylab='Precipitation (cm)')
plot(gdd ~ date, data=cobs10, type='l', ylab='Thermal units')
This looks okay, but not with ticks on top of the plots. Not good. Naturally, we can enable ticks in the first two plots (with ''plot(..., xaxt='n')''), but this will distort the bottom plot. So you will need to do so for all three plots and then add the axis to the outer plotting region.
par(mfrow=c(3,1), mar=c(0.6, 5.1, 0, 0.6), oma=c(5.1, 0, 1, 0))
plot(temp ~ date, data=cobs10, type='l', xaxt='n', ylab='Temperatur (C)')
plot(precip ~ date, data=cobs10, type='l', xaxt='n', ylab='Precipitation (cm)')
plot(gdd ~ date, data=cobs10, type='l', xaxt='n', ylab='Thermal units')
ticks <- seq(from=min(cobs10$date), by='2 months', length=7)
lbl <- strftime(ticks, '%b')
axis(side=1, outer=TRUE, at=ticks, labels=lbl)
mtext('2010', side=1, outer=TRUE, line=3, cex=0.67)
Since ''pretty'' doesn't behave as we want it to, we use ''seq'' to make the sequence of x-axis ticks. Then we format the dates to just display an abbreviation of the month name, but this is done with regard to local settings (I live in Denmark), see ''locale''.
To add the axis-ticks and a label to the outer region, we must remember to specify ''outer=TRUE''; otherwise it is added to the last subplot.
Also note that I specified ''cex=0.67'' to match the font size of the x-axis to the y-axis.
Now I agree that displaying the thermal units in a individual subplot is not optimal, although it is the correct way of displaying it. But there was the issue with the ticks. What we really want is to display some nice values that clearly display that they are not linear. But your data does not necessarily contain these nice values, so we will have to interpolate them ourselves.
For this, I use the ''splinefun''
lbl <- c(0, 2, 200, 1000, 2000, 3000, 4000)
thermals <- splinefun(cobs10$gdd, cobs10$date) # thermals is a function that returns the date (as an integer) for a requested value
thermals(lbl)
## [1] 14649.00 14686.79 14709.55 14761.28 14806.04 14847.68 14908.45
ticks <- as.Date(thermals(lbl), origin='1970-01-01') # remember to specify an origin when converting an integer to a Date.
Now the thermal ticks are in place, lets try it.
par(mfrow=c(2,1), mar=c(0.6, 5.1, 0, 0.6), oma=c(5.1, 0, 4, 0))
plot(temp ~ date, data=cobs10, type='l', xaxt='n', ylab='Temperatur (C)')
plot(precip ~ date, data=cobs10, type='l', xaxt='n', ylab='Precipitation (cm)')
usr <- par('usr')
x.pos <- (usr[2]+usr[1])/2
ticks <- seq(from=min(cobs10$date), by='2 months', length=7)
lbl <- strftime(ticks, '%b')
axis(side=1, outer=TRUE, at=ticks, labels=lbl)
mtext('2010', side=1, at=x.pos, line=3)
lbl <- c(0, 2, 200, 1000, 2000, 3000, 4000)
thermals <- splinefun(cobs10$gdd, cobs10$date) # thermals is a function that returns the date (as an integer) for a requested value
ticks <- as.Date(thermals(lbl), origin='1970-01-01') # remember to specify an origin when converting an integer to a Date.
axis(side=3, outer=TRUE, at=ticks, labels=lbl)
mtext('Thermal units', side=3, line=15, at=x.pos)
Update I changed the mtext function calls in the last code block to ensure that the x-axis texts are centred on the plotting region, not the entire region. You might want to tweak the vertical position by changing the line-argument.

How to delete some of scale? [duplicate]

I can get photo11 with the following code,how can i fix my code to change photo1 into photo2?
x = seq(0.5, 0.9, length = 200)
y = dnorm(x,0.7,0.0458)
plot(x, y,type="l",xlab="my_x_lab")
this is a photo1.jpg
this is a photo2.jpg
and ,how to fix my code to change photo2.jpg into photo3.jpg?there are
only two scales(0.7,0.8) in the x_lab.
this is a photo3.jpg
to fix the code to get rid of y in the y_lab to change photo3.jpg into photo4.jpg?
this is a photo4.jpg.
This will do it. xaxt='n', ann=FALSE removes the x-axis and annotations. axis(...) puts the x-axis only at the specified points. mtext() will put marginal text on the bottom axis.
x <- seq(0.5, 0.9, length = 200)
y <- dnorm(x,0.7,0.0458)
plot(x, y, type="l", xaxt='n', ann=FALSE)
axis(1, at=c(0.7, 0.8))
mtext("my_x_lab", 1, at=0.9, line=2)
Suppress the x axis and add blanks for the labels where you do not want them.
plot(x, y, type="l", yaxt="n",ann=FALSE,bty="n", xaxt="n")
axis(1, at=c(0.5, 0.6, 0.7, 0.8, 0.9), labels=c("", "", 0.7, 0.8, 0.9) )
mtext("Proportions", 1, at=0.9, line=2)
If you insist on omitting the ticks in the left hand side its going to be more difficult because the base line will only extend from the first tick.
Except this answer is better than mine.
how to draw the graph in R?
I guess it means this is homework? Oh NOOOO, it's the same poster... you are posting duplicate questions? Bad poster , bad poster. Shame on you.

Resources