I'm having the code as like below. But I'm not getting all the x axis labels and it is not displaying in 45 degree when I try to have this in pdf. Since I'm new, Please help me correct this option.
pdf(file="figure.pdf", height=3.5, width=5, onefile=TRUE)
Runtime <- c(579,0,581,610,830,828,592,651,596,596,591,581,587,594,604,606,447,434,445)
Runtime
g_range <- range(0,Runtime)
g_range
plot(Runtime, type="o", col="blue", ylim=g_range,axes=FALSE, ann=FALSE)
lab=c('2011-07-20','2011-08-03','2011-08-10','2011-08-17','2011-08-24','2011-08-25','2011-08-27','2011-08-31','2011-09-07','2011-09-10','2011-09-14','2011-09-21','2011-09-28','2011-10-05','2011-10-06','2011-10-07','2011-10-13','2011-10-19','2011-10-31')
box()
lab
axis(1, at=1:19, lab=F)
text(axTicks(1), par("usr")[3] - 2, srt=45, adj=1, labels=lab, xpd=T, cex=0.8)
axis(2, las=1, at=500*0:g_range[2])
title(main="Runtime", col.main="red", font.main=4)
title(xlab="Build", col.lab=rgb(0,0.5,0))
title(ylab="MS", col.lab=rgb(0,0.5,0))
legend(1, g_range[2], c("AveElapsedTime"), cex=0.8, col=c("blue"), pch=21, lty=1);
dev.off()
When I run your code, I do not get the image you show. The problem is this line:
text(axTicks(1), par("usr")[3] - 2, srt=45, adj=1, labels=lab, xpd=T, cex=0.8)
as axTicks(1) returns:
> axTicks(1)
[1] 5 10 15
So what is happening is that your 19 labels are being plotted at those 3 locations.
If you want to plot at the locations of the ticks (1:19) then:
text(1:19, par("usr")[3] - 2, srt=45, adj=1, labels=lab, xpd=T, cex=0.8)
will work.
Here is a full example based on your code.
Runtime <- c(579,0,581,610,830,828,592,651,596,596,591,581,587,
594,604,606,447,434,445)
g_range <- range(0,Runtime)
lab <- c('2011-07-20','2011-08-03','2011-08-10','2011-08-17','2011-08-24',
'2011-08-25','2011-08-27','2011-08-31','2011-09-07','2011-09-10',
'2011-09-14','2011-09-21','2011-09-28','2011-10-05','2011-10-06',
'2011-10-07','2011-10-13','2011-10-19','2011-10-31')
## plot
op <- par(mar = c(6,4,4,2) + 0.1) ## bigger bottom margin
plot(Runtime, type="o", col="blue", ylim=g_range, axes=FALSE, ann=FALSE)
box()
axis(1, at=1:19, lab=FALSE)
text(1:19, par("usr")[3] - 40, srt=45, adj=1.2, labels=lab, xpd=T, cex=0.7)
axis(2, las=1, at=500*0:g_range[2])
title(main="Runtime", col.main="red", font.main=4)
title(xlab="Build", col.lab=rgb(0,0.5,0), line = 4.5)
title(ylab="MS", col.lab=rgb(0,0.5,0))
legend("topright", c("AveElapsedTime"), cex=0.8, col=c("blue"), pch=21, lty=1)
## reset par
par(op)
This might be better handled using function in the gridBase package though, which allows grid and base graphics to intermingle. The reason I say it might be better is that you can specify that the y coordinate be set in terms of numbers of lines rather that trying to work out a suitable value for y in terms of the plotted data.
Here is an example:
## load gridBase
require(gridBase)
## do the base plot parts
op <- par(mar = c(6,4,4,2) + 0.1) ## bigger bottom margin
plot(1:19, Runtime, type="o", col="blue", ylim=g_range, axes=FALSE, ann=FALSE)
box()
axis(1, at=1:19, lab=FALSE)
axis(2, las=1, at=500*0:g_range[2])
title(main="Runtime", col.main="red", font.main=4)
title(xlab="Build", col.lab=rgb(0,0.5,0), line = 4.5)
title(ylab="MS", col.lab=rgb(0,0.5,0))
legend("topright", c("AveElapsedTime"), cex=0.8, col=c("blue"), pch=21, lty=1)
## at this point, DO NOT alter the dimensions of the plotting window
## now do the grid business
vps <- baseViewports()
pushViewport(vps$inner, vps$figure, vps$plot)
## this adds the text
grid.text(lab, x = unit(1:19, "native"), y = unit(-1, "lines"),
just = "right", rot = 60, gp = gpar(cex = 0.7))
## this finishes off the viewport - you have to do this or things will go wrong:
popViewport(3)
## reset par
par(op)
Note this can be a bit picky on screen, rerunning the gridBase example on my R 2.13.2 install doesn't produce any labels. Closing the device and then running the code afresh works though. I don't think this should be a problem if you are drawing to a pdf() device.
Related
Can someone help me. I have a dataset that had NA values that I have interpolated with zoo. I have added a 'colour column' in the hope that I could create a line plot (time series) with the interpolated values plotted in a different colour to the rest of the line. That is, the segment of the line defined by the point immediately before and immediately after the interpolated point should be red, and not black.
I've attached an example of my table here (where the colour is 'red' defines the values that have been interpolated). I've also put an image of the graph so far and the desired output here too:
https://drive.google.com/folderview?id=0B_eJi0urUAzFM0JBS1ZIbUdGck0&usp=drive_web
This is my code thus far. The 'lines' part of the code is where I hoped to define the colour as the column in the data frame:
par(mfrow=c(2,1), mar=c(4,4.5,2,2), mgp=c(2,0.6,0))
x.limit <- round(range(UN.GRACE.Int$DecimDate), 2)
plot(NULL, type="n", xlim=x.limit, ylim=c(-20, 25), xlab="Year", ylab="GRACE-TWS (cm)", axes=F)
box(lwd=1.5)
abline(h=0, col="gray50", lty=1)
axis(1, seq(2003, 2012, 1), cex.axis=0.8)
axis(2, seq(-20, 25, 5), las=1, cex.axis=0.8)
minor.tick(nx=4, ny=0, tick.ratio=0.5)
lines(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1], type="l", lwd=3, col=UN.GRACE.Int[,3])
tws.slope <- round(as.vector(coef(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1]))[2]), 2)
tws.sdev <- round(as.vector(coef(summary(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1])))[, "Std. Error"][2]), 2)
abline(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1]), lwd=2.5, lty=2, col=2)
mtext(paste("Trend (cm/year): ", tws.slope, "±", tws.sdev, sep=""), cex=0.8, side=1, line=-1.1)
Any help would be appreciated - Thanks
If I understand this correctly, you want the interpolated points to show up with a different color. You can accomplish this using the type="o" option in R, which gives over-plotted lines. Here's some adjusted code that produces the following plot. I took the minor.tick command out because it must have been from a package I don't have, but otherwise it works fine (using R 2.15.3 on my local machine).
You'll notice that I just plot the item directly, rather than calling plot to NULL and then adding in lines. This simplifies the code substantially. You can play with the pch parameter in the plot call to change the symbols used, and also alter the lwd parameters as needed. In fact, you could easily give a different value to pch for the interpolated values, like you did color - it accepts a vector as an argument.
par(mar=c(4,4.5,2,2), mgp=c(2,0.6,0))
x.limit <- round(range(UN.GRACE.Int$DecimDate), 2)
plot(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1],
type="o",
pch=18,
col=UN.GRACE.Int[,3],
xlim=x.limit,
ylim=c(-20, 25),
xlab="Year",
ylab="GRACE-TWS (cm)",
axes=F)
box(lwd=1.5)
abline(h=0, col="gray50", lty=1)
axis(1, seq(2003, 2012, 1), cex.axis=0.8)
axis(2, seq(-20, 25, 5), las=1, cex.axis=0.8)
tws.slope <- round(as.vector(coef(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1]))[2]), 2)
tws.sdev <- round(as.vector(coef(summary(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1])))[, "Std. Error"][1]), 2)
abline(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1]), lwd=2.5, lty=2, col=2)
mtext(paste("Trend (cm/year): ", tws.slope, "±", tws.sdev, sep=""), cex=0.8, side=1, line=-1.1)
You could also add the points later if you JUST want to see the points where the data was interpolated. This could be done as follows:
par(mar=c(4,4.5,2,2), mgp=c(2,0.6,0))
x.limit <- round(range(UN.GRACE.Int$DecimDate), 2)
plot(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1],
type="l",
pch=18,
col="black",
xlim=x.limit,
ylim=c(-20, 25),
xlab="Year",
ylab="GRACE-TWS (cm)",
axes=F)
box(lwd=1.5)
abline(h=0, col="gray50", lty=1)
axis(1, seq(2003, 2012, 1), cex.axis=0.8)
axis(2, seq(-20, 25, 5), las=1, cex.axis=0.8)
tws.slope <- round(as.vector(coef(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1]))[2]), 2)
tws.sdev <- round(as.vector(coef(summary(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1])))[, "Std. Error"][3]), 2)
abline(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1]), lwd=2.5, lty=2, col=2)
mtext(paste("Trend (cm/year): ", tws.slope, "±", tws.sdev, sep=""), cex=0.8, side=1, line=-1.1)
points(x=UN.GRACE.Int[UN.GRACE.Int$Col.CSR=="red",1],
y=UN.GRACE.Int[UN.GRACE.Int$Col.CSR=="red",2],
pch=16,
col="red")
EDITED TO ADD: This is a way to color the line segments themselves by overplotting the original plot, assuming the distance to be colored is always of length one. It uses a quick'n'dirty for() loop, but it could be made into a function if you wanted.
par(mar=c(4,4.5,2,2), mgp=c(2,0.6,0))
x.limit <- round(range(UN.GRACE.Int$DecimDate), 2)
plot(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1],
type="l",
pch=18,
col="black",
xlim=x.limit,
ylim=c(-20, 25),
xlab="Year",
ylab="GRACE-TWS (cm)",
axes=F)
box(lwd=1.5)
abline(h=0, col="gray50", lty=1)
axis(1, seq(2003, 2012, 1), cex.axis=0.8)
axis(2, seq(-20, 25, 5), las=1, cex.axis=0.8)
tws.slope <- round(as.vector(coef(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1]))[2]), 2)
tws.sdev <- round(as.vector(coef(summary(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1])))[, "Std. Error"][5]), 2)
abline(lm(UN.GRACE.Int[,2] ~ UN.GRACE.Int[,1]), lwd=2.5, lty=2, col=2)
mtext(paste("Trend (cm/year): ", tws.slope, "±", tws.sdev, sep=""), cex=0.8, side=1, line=-1.1)
line_segs <- cbind(lstart=UN.GRACE.Int[which(UN.GRACE.Int$Col.CSR=="red")-1,c("DecimDate","CSR")],
lend=UN.GRACE.Int[which(UN.GRACE.Int$Col.CSR=="red")+1,c("DecimDate","CSR")])
for(x in 1:nrow(line_segs)) {
lines(x=c(line_segs[x,1],line_segs[x,3]),
y=c(line_segs[x,2],line_segs[x,4]),
lwd=3,
col="red")
}
I tried to plot a horizontal y label using the following code:
require(grDevices)
par(mfrow=c(2,1), mar=c(0,3,0,0.5)+0.1, oma=c(3,0,0.5,0)+0.1,
mgp=c(2,1,0), cex=tcex)
par(las=1)
#pl-d001
plot(1, type="n", yaxt='n', xaxt='n', xaxs="i", yaxs="i", xlab="xlabel",
ylab=expression("axis "*italic(r[infinity])), xlim=c(0, 0.4), ylim=c(0, 1))
But, I only get a normal (vertical) Y label. What is wrong here?
As #rawr said in the comments, your best chance is with mtext:
plot(1, type="n", yaxt='n', xaxt='n', xaxs="i", yaxs="i",
xlab="xlabel", ylab="", xlim=c(0, 0.4), ylim=c(0, 1))
mtext(expression("axis "*italic(r[infinity])),side=2,las=1,line=1)
The reason why you can't do that directly from plot is that, internally, plot uses title to draw those labels and title (for some reason) doesn't take las or srt as arguments.
I need a two y-axes figure. hrbrmstr suggested to use simple plots. But when adapting the graph to my setting I observed I cannot add the ylab on the right hand side, getting a wired error:
Error in axis(4, ylim = c(0, 1), col = "black", col.axis = "black", las = 1, :
'labels' is supplied and not 'at'
Is this avoidable?
look at the code the bottom line fpr SOURCE OF ERROR
featPerf <- data.frame( expS=c("1", "2", "3", "4"),
exp1=c(1000, 0, 0, 0),
exp2=c(1000, 5000, 0, 0),
exp3=c(1000, 5000, 10000, 0),
exp4=c(1000, 5000, 10000,20000),
accuracy=c(0.4, 0.5, 0.65, 0.9) )
# make room for both axes ; adjust as necessary
par(mar=c(5, 5, 5, 7) + 0.2)
# plot the bars first with no annotations and specify limits for y
#barplot(as.matrix(featPerf[,2:5]), axes=FALSE, xlab="", ylab="", ylim=c(0, max(colSums(featPerf[2:5]))))
barplot(as.matrix(featPerf[,2:5]), axes=FALSE, xlab="", ylab="", beside=TRUE)
# make the bounding box (or not...it might not make sense for your plot)
#box()
# now make the left axis
axis(2, ylim=c(0, max(colSums(featPerf[2:5]))), col="black", las=1)
# start a new plot
par(new=TRUE)
# plot the line; adjust lwd as necessary
plot(x=1:4, y=featPerf[,6], xlab="Experiments", ylab="Abs. # of Features", axes=FALSE, type="l", ylim=c(0,1), lwd=5)
# annotate the second axis -- SOURCE OF ERROR -> VVVVVVVVVVVVVVVVVV
axis(4, ylim=c(0,1), col="black", col.axis="black", las=1, labels="Accuracy")
Like this?
par(mar=c(4,4,1,4) + 0.2)
barplot(as.matrix(featPerf[,2:5]), axes=FALSE, xlab="", ylab="", beside=TRUE)
axis(2, ylim=c(0, max(colSums(featPerf[2:5]))), col="black", las=1)
par(new=TRUE)
plot(x=1:4, y=featPerf[,6], xlab="Experiments", ylab="Abs. # of Features", axes=FALSE, type="l", ylim=c(0,1), lwd=5, col="blue")
axis(4, ylim=c(0,1), col="blue", col.axis="blue", las=1)
mtext("Accuracy",4,line=2, col="blue")
For the record, it is never a good idea to stack plots on top of each other this way (with two axes). I've made the line and the axis the same color in an attempt to draw attention to what you are doing, but this is still a very bad idea.
First of all it is not advisable to use two Y-axes in a same plot.
If you add at argument to the axis call, you get the name "Accuracy" on the right hand side of the plot.
axis(4, ylim=c(0,1), col="black", col.axis="black", las=1, labels="Accuracy",
at = .5)
I have 3 sets of data that I am trying to plot on a single plot. The first data set x values range from ~ 1 to 1700 whereas the other two data sets x values are less than 20. Therefore I want to plot them on a log axis to show variations in all the data sets. However I do not want to transform the data as I want to be able to read the values off the graph. The x axis labels I would like are 1, 10, 100 and 1000 all equally spaced. Does anyone know how to do this? I can only find examples where the data is log as well as the axis. I have attached the code I am currently using below:
Thanks in advance for any help given.
Holly
Stats_nineteen<-read.csv('C:/Users/Holly/Documents/Software Manuals/R Stuff/Stats_nineteen.csv')
attach(Stats_nineteen)
x<-Max
x1<-Min
x2<-Max
y1<-Depth
y2<-Depth
par(bg="white")
par(xlog=TRUE)
plot(x2,y1, type="n", ylim=c(555,0), log="x", axes=FALSE, ann=FALSE)
box()
axis(3, at=c(1,10,100,1000), label=c(1,10,100,1000), pos=0, cex.axis=0.6)
axis(1, at=c(1,10,100,1000), label=c(1,10,100,1000), cex.axis=0.6)
axis(2, at=c(600,550,500,450,400,350,300,250,200,150,100,50,0), label=c
(600,"",500,"",400,"",300,"",200,"",100,"",0), cex.axis=0.6)
mtext("CLAST SIZE / mm", side=3, line=1, cex=0.6, las=0, col="black")
mtext("DEPTH / m", side=2, line=2, cex=0.6, las=0, col="black")
grid(nx = NULL, ny = NULL, col = "lightgray", lty = "solid",
lwd = par("lwd"), equilogs = TRUE)
par(new=TRUE)
lines(x1,y1, col="black", lty="solid", lwd=1)
lines(x2,y2, col="black", lty="solid", lwd=1)
polygon(c(x1,rev(x2)), c(y1,rev(y2)), col="grey", border="black")
par(new=TRUE)
plot(x=Average,y=Depth, type="o",
bg="red", cex=0.5, pch=21,
col="red", lty="solid",
axes=FALSE, xlim=c(0,1670), ylim=c(555,0),
ylab = "",xlab = "")
par(new=TRUE)
plot(x=Mode,y=Depth, type="o",
bg="blue", cex=0.5, pch=21,
col="blue", lty="solid",
axes=FALSE, xlim=c(0,1670), ylim=c(555,0),
ylab = "",xlab = "")
You can do this in ggplot using scale_x_log
so something like:
myplot <- ggplot( StatsNinetee,
aes (x = myResponse,
y = myPredictor,
groups = myGroupingVariable) ) +
geom_point() +
scale_x_log()
myplot
also, avoid attach() it can give odd behavior.
When I try to give the title name as a function argument for Z and for legend, it is not working.. I also tried by just giving z. Please advise..
drawGraph <- function(x, y, z) {
g_range <- range(0,x)
plot(x, type="o", col="blue", ylim=g_range,axes=FALSE, ann=FALSE)
box()
axis(1, at=1:19, lab=FALSE)
text(1:19, par("usr")[3] - 2, srt=45, adj=1.2, labels=y, xpd=T, cex=0.3)
axis(2, las=1, at=500*0:g_range[2])
main_title<-as.character(z)
title(main=main_title, col.main="red", font.main=4)
title(xlab="Build", col.lab=rgb(0,0.5,0))
title(ylab="MS", col.lab=rgb(0,0.5,0))
legend("topright", g_range[2], c("z"), cex=0.8, col=c("blue"), pch=21, lty=1);
}
drawGraph(AET, lab, AveElapsedTime)
If you wanted to construct a title outside of the function you could use an as.expression(z). This would let the title be "The average time with ranges: 1 to 8" and the values in the range would be adjusted "on the fly".
drawGraph <- function(x, y, z) {
g_range <- range(0,x)
plot(x, type="o", col="blue", ylim=g_range,axes=FALSE, ann=FALSE)
box()
axis(1, at=1:19, lab=FALSE)
text(1:19, labels=y,par("usr")[3] - 2, srt=45, adj=1.2, xpd=T, cex=0.3)
axis(2, las=1, at=500*0:g_range[2])
main_title<-as.expression(z)
title(main=main_title, col.main="red", font.main=4)
title(xlab="Build", col.lab=rgb(0,0.5,0))
title(ylab="MS", col.lab=rgb(0,0.5,0))
legend("topright", g_range[2], c("z"), cex=0.8, col=c("blue"), pch=21, lty=1);
}
x <- rpois(19, 4)
AveElapsedTime=paste("The average time with ranges:",
round(range(x)[1], 3),
"to" , round(range(x), 3)[1])
lab=1:19
drawGraph(AET, lab, AveElapsedTime)
Is AveElapsedTime a variable? If yes,this works:
AveElapsedTime <- 50
drawGraph(AET, lab, AveElapsedTime)
If it's just text, this works:
drawGraph(AET, lab, "AveElapsedTime")
Quote AveElapsedTime so that it's treated as a string and not a variable:
drawGraph(AET, lab, "AveElapsedTime")