I have eliminated labels on the y axis because only the relative amount is really important.
w <- c(34170,24911,20323,14290,9605,7803,7113,6031,5140,4469)
plot(1:length(w), w, type="b", xlab="Number of clusters",
ylab="Within-cluster variance",
main="K=5 eliminates most of the within-cluster variance",
cex.main=1.5,
cex.lab=1.2,
font.main=20,
yaxt='n',lab=c(length(w),5,7), # no ticks on y axis, all ticks on x
family="Calibri Light")
However, suppressing those tick labels leaves a lot of white space between the y axis label ("Within-cluster variance") and the y axis. Is there a way to nudge it back over? If I somehow set the (invisible) tick labels to go inside the axis, would the axis label settles along the axis?
Try setting ylab="" in your plot call and use title to set the label of the y-axis manually. Using line you could adjust the position of the label, e.g.:
plot(1:length(w), w, type="b", xlab="Number of clusters", ylab="",
main="K=5 eliminates most of the within-cluster variance",
cex.main=1.5,
cex.lab=1.2,
font.main=20,
yaxt='n',lab=c(length(w),5,7), # no ticks on y axis, all ticks on x
family="Calibri Light")
title(ylab="Within-cluster variance", line=0, cex.lab=1.2, family="Calibri Light")
Please read ?title for more details.
Adjust mgp, see ?par
title(ylab="Within-cluster variance", mgp=c(1,1,0), family="Calibri Light",cex.lab=1.2)
Related
I want to make a plot of 4 sets of data points using dual y-axis. The first two are on the left y-axis and last two are on the right y-axis. The first two belong to a set of numbers ranging from 5000 to 50,000. Second two sets of data belong range from 1-100. I want to plot it so that it is easily discernable that the two axis are not only on different scales but also the height between points from the two different sets with distinct ranges is obviously big. I don't want to be able to draw a horizontal line that would suggest some number from the left-y-axis can be mapped bijectively to some number on the right y-axis. I want to make it such that a horizontal line through any points from the left y-axis and right y-axis would belong to only one set related to either left or right axis.
How can I plot with 2 different y-axes?. There's
I'd use twoord.plot
From plotrix v3.7-5
by Jim Lemon but that has the disadvantage than base R beacause I can't add 4 sets of data into one plot. I can only use 2 sets of (x,y) pairs with 2--ord plot. I can theoretically plot n sets of (x,y) pairs using base R.
None
Here's what doesn't work:
time <- seq(0,72,12)
betagal.abs <- c(0.05,0.18,0.25,0.31,0.32,0.34,0.35)
cell.density <- c(0,1000,2000,3000,4000,5000,6000)
## add extra space to right margin of plot within frame
par(mar=c(5, 4, 4, 6) + 0.1)
## Plot first set of data and draw its axis
plot(time, betagal.abs, pch=16, axes=FALSE, ylim=c(0,1), xlab="", ylab="",
type="b",col="black", main="Mike's test data")
axis(2, ylim=c(0,1),col="black",las=1) ## las=1 makes horizontal labels
mtext("Beta Gal Absorbance",side=2,line=2.5)
box()
## Allow a second plot on the same graph
par(new=TRUE)
## Plot the second plot and put axis scale on right
plot(time, cell.density, pch=15, xlab="", ylab="", ylim=c(0,7000),
axes=FALSE, type="b", col="red")
## a little farther out (line=4) to make room for labels
mtext("Cell Density",side=4,col="red",line=4)
axis(4, ylim=c(0,7000), col="red",col.axis="red",las=1)
## Draw the time axis
axis(1,pretty(range(time),10))
mtext("Time (Hours)",side=1,col="black",line=2.5)
## Add Legend
legend("topleft",legend=c("Beta Gal","Cell Density"),
text.col=c("black","red"),pch=c(16,15),col=c("black","red"))
Not quite sure what you're after but you can add an extra 'line per plot' by using lines.
I've edited your code
## Plot first set of data and draw its axis
plot(time, betagal.abs, pch=16, axes=FALSE, ylim=c(0,1), xlab="", ylab="",
type="b",col="black", main="Mike's test data")
lines(seq(0, 1, 0.02), type = 'o')
axis(2, ylim=c(0,1),col="black",las=1) ## las=1 makes horizontal labels
mtext("Beta Gal Absorbance",side=2,line=2.5)
box()
## Allow a second plot on the same graph
par(new=TRUE)
## Plot the second plot and put axis scale on right
plot(time, cell.density, pch=15, xlab="", ylab="", ylim=c(0,7000),
axes=FALSE, type="b", col="red")
lines(seq(0, 5000, 10), type = 'o', col = 'red')
## a little farther out (line=4) to make room for labels
mtext("Cell Density",side=4,col="red",line=4)
axis(4, ylim=c(0,7000), col="red",col.axis="red",las=1)
which produces this:
Please let me know if this wasn't what you were after.
How can I move the y axis label from the left to the right of the plot area and the x-axis label from below to above the plot area in the following graph? Thanks
xleft<-c(1,2,2.5)
xright<-c(2,2.5,2.75)
ybottom<-c(1,2,2.5)
ytop<-c(2,2.5,2.75)
par(mar = c(15,15,2.75,2.75) + 0.1)
plot(c(1,3),c(1,3),type="n",main="title",xlab="xlab-move me above plot",ylab="ylab-move me right of plot",axes=F,asp=1)
axis(1,pos=1)
axis(2,pos=1)
rect(xleft,ybottom,xright,ytop,col=c("blue","red","green"))
#Label position along axes
x.label.position<-(xleft+xright)/2
y.label.position<-(ybottom+ytop)/2
#Labels
x.label<-c("Long species Name1","Long species Name2","Long species Name3")
y.label<-c("Long species Name4","Long species Name5","Long species Name5")
text(par()$usr[1]-0.5,y.label.position,y.label,xpd=TRUE,adj=1)
text(y=par()$usr[3]-0.5,x=x.label.position,x.label,xpd=TRUE,adj=1,srt=90)
par(xpd=TRUE)
legend(-0.1,0,legend=c("Species A","Species B","Species C"),fill=c("blue", "red", "green"))
Ploting axes on the right and top sides of a plot
By default R will plot the x-axis below the plot area and the y-axis to the left of it. You can change this behaviour in this way:
plot(1:100, cumsum(rnorm(100)), type="l", axes=FALSE) # Do not plot any axes
axis(3) # Draw the x-axis above the plot area
axis(4) # Draw the y-axis to the right of the plot area
box()
To also move the labels you set ann=FALSE or xlab="", ylab="" and add them afterwards with mtext, where side=1 is bottom, 2 is left, 3 is top, 4 is right. line controls the distance from the plot area.
plot(1:100, cumsum(rnorm(100)), type="l", axes=FALSE, ann=FALSE)
axis(3)
box()
mtext("Top axis", side=3, line=3)
Changing distance between labels, ticks and plot area.
Use the mgp parameter to control these details, either before the call to plot, like this
par(mgp=c(axis.title.position, axis.label.position, axis.line.position))
or in the plot command itself, like this
plot(1:100, cumsum(rnorm(100)), type="l", mgp=c(2,1,.5), las=1)
Also note the las parameter that turns all tick labels horisontal, which makes them easier to read.
In the following example, I plot a custom tick mark at .95 (edited to make labels horizontal as per Thomas' suggestion):
d = matrix(runif(40), ncol=4)
colnames(d) = c('a','b','c','d')
barplot(
d,
beside=T,
col=c('#CD4E3C', '#816DC3','#569340', '#A87929'),
ylim=c(0,1),
cex.axis=.80,
main= 'Title',
las=1
)
abline(h= 1:10/10, col = 'lightgray', lty=3)
axis(side=2, at=c(.95), cex.axis=.75, tck=-.01, las=1)
abline(h= .95, col = '#000000', lty=3)
Which gives:
My custom label is too close to the regular label (which I also need), and I'd like to bring the label closer to the tick mark. I looked through
help(par)
How might a bring that label closer to the axis?
EDIT:
Making the tick mark labels horizontal helped, but I'd still like to indent the label for .95 to reflect the shortened tick mark.
Quick solution is to put las=2 in both your barplot() and axis() calls to make labels horizontal and they'll be clearer.
EDIT: Use mtext instead of axis:
mtext("0.95",2,.5,at=.95,las=2,cex=.75)
Basically I only want to draw the x, y, z axis with empty plot, but with x, y, z of my own labels on it. Is it possible to do it in R? I know how to draw it in 2d plot.
Here is your answer:
library(scatterplot3d)
scatterplot3d(0,0,0, pch="", xlab="X", ylab="Y",zlab="Z",
xlim=c(0,1), ylim=c(0,1), zlim=c(0,1))
The position of Y label seems a bit strange. This is a limitation of this package. So you may set ylab="" and then manually put the label to your desired place by text(x, y, "Y")
I would like to make a plot with 4 axes in R so that it looks similar to this plot:
I've looked at the Quick-R website for advice and modified one of their examples (called A Silly Axis Example):
# specify the data
x <- c(1:5); y <- x/2;
w <- c(2:4)
z <- c(1:5)
# create extra margin room on the right for an axis
par(mar=c(5, 4, 4, 8) + 0.1)
# plot x vs. y
plot(x, y,type="b", pch=21, col="red",
yaxt="n", lty=3, xlab="", ylab="")
# add x vs. 1/x
lines(x, z, type="b", pch=22, col="blue", lty=2)
# draw an axis on the left
axis(2, at=x,labels=x, col.axis="red", las=2)
# draw an axis on the right, with smaller text and ticks
axis(4, at=w,labels=round(w,digits=2),
col.axis="blue", las=2, cex.axis=0.7, tck=-.01)
# draw an axis on the top
axis(3, at=z,labels=round(z,digits=2),
col.axis="blue", las=2, cex.axis=0.7, tck=-.01)
# add a title for the right axis
mtext("L", side=3, line=3, cex.lab=1,las=2, col="blue")
# add a title for the right axis
mtext("OSR", side=4, line=3, cex.lab=1,las=2, col="red")
# add a main title and bottom and left axis labels
title("", xlab="GSI", ylab="FSI")
This code produces the following plot:
I'm having difficulty figuring out how different axes can have different scales. For example, I want the top axis L, to go from 5 - 13, but if I set z <-c(5:13) it will not set the axis to these values. However, I can overwrite what the labels are:
axis(3, at=z,labels=round(c(9:13),digits=2), col.axis="blue",
las=2, cex.axis=0.7, tck=-.01)
but then if I want to plot a point with these four parameters, the point will not show up in the correct place. How should I do this?
One (perhaps cumbersome) option would be to write conversion functions that transform values between your two scales. Assuming you know the data ranges for both the top and bottom axes ahead of time, you could write a function like this:
convertScaleToBottom <- function(x,botRange,topRange){
temp <- (x - topRange[1]) / (topRange[2] - topRange[1])
return(botRange[1] + (temp * (botRange[2] - botRange[1])))
}
that takes a set of values, x, in the top axis scale and converts them to the bottom axis scale. Then you can plot the converted values and retain the originals as the labels:
z1 <- 5:13
z1Adj <- convertScaleToBottom(z1,range(x),range(z1))
# draw an axis on the top
axis(3, at=z1Adj,labels=round(z1,digits=2),
col.axis="blue", las=2, cex.axis=0.7, tck=-.01)
This method is easily modified to reverse the order of the top axis:
convertScaleToBottomRev <- function(x,botRange,topRange){
temp <- (x - topRange[1]) / (topRange[2] - topRange[1])
return(botRange[2] - (temp * (botRange[2] - botRange[1])))
}