I have generated a bar plot/histogram for my data which shows the number of transactions for pack size. However, labels on x axis for the bars are out of the margin. The plot is presented below.
I have tried to fix this by setting the outer margin to par(oma=c(3,3,0,0)). Here is my new plot.
Although, the labels are inside the graph margin, but the x-axis title is still overlapped with the labels. How should I adjust the axis title so it is not overlapped with the labels?
Any suggestions would be very much appreciated!
Use axis and mtext.
par(mar=c(11, 6, 4, 2))
b <- barplot(data$v, ylim=c(0, 2e4), yaxt='n',
main='Number of Transactions by Life Stage Histogram'
)
mtext(data$l, 1, .5, at=b, las=2, cex=.7)
axis(2, labels=F)
mtext(axTicks(2), 2, .75, at=axTicks(2), las=2)
mtext('Life Stage', 1, 9)
mtext('Freequency', 2, 4)
Or maybe that might be better:
par(mar=c(3, 5, 4, 3))
b <- barplot(data$v, ylim=c(0, 15e3), ylab='Frequency', yaxt='n',
main='Number of Transactions by Life Stage'
)
axis(2, labels=F)
mtext(axTicks(2), 2, .75, at=axTicks(2), las=2, cex=.8)
y <- (data$v) * c(1, 1, 1, 0, 0, 0, 0) + 500
text(b, y, data$l, srt=90, adj=0, cex=.7)
mtext('Life Stage', 1, 1)
Data:
data <- structure(list(l = c("MIDAGE SINGLES/COUPLES", "NEW FAMILIES",
"OLDER FAMILIES", "OLDER SINGLES/COUPLES", "RETIREES", "YOUNG FAMILIES",
"YOUNG SINGLES/COUPLES"), v = c(7500, 2500, 1000, 15000, 15100,
10000, 15000)), class = "data.frame", row.names = c(NA, -7L))
Taking jay.sf example as one for any plot we could add:
title(xlab = "My Label", line = 10)
Where line is adaptable: 10 or 9 or 8 etc...
plot.new()
par(mar=c(11, 6, 4, 2))
b <- barplot(data$v, ylim=c(0, 2e4), yaxt='n',
main='Number of Transactions by Life Stage Histogram'
)
mtext(data$l, 1, .5, at=b, las=2, cex=.7)
axis(2, labels=F)
mtext(axTicks(2), 2, .75, at=axTicks(2), las=2)
mtext('Life Stage', 1, 9)
mtext('Freequency', 2, 4)
title(xlab = "My Label", line = 10)
I have written the following code below. I would like to overlay a bar graph with a line graph. The code I have does it all but with just one problem. I would like the points on the line graph to be in the center of the bar graph, i.e. they should shift to the left a little bit. where Im I missing it? If this can be done in ggplot as well I would be happy too. but even base r would do
par(mai = c ( 1 , 2, 1, 1), omi = c(0, 0, 0, 0))
yy <- c(31,31,31,50,50,61,69,75,80,88,94,101,108,115,121,124,125,125,125,126,127)
name1 <- c ("15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35")
xx <- barplot(yy, ylab = "", names.arg = name1, ylim = c(0, 140),col="steelblue")
text(xx, yy + 3, labels = as.character(yy),srt=45)
mtext(2,text="",line=2)
par(new = T)
xx2 <- c(15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35)
yy2 <- c(379,474,579,725,922,1181,1473,1846,2316,2962,3688,4786,6069,7605,9504,10680,11074,11074,11074,11483,11484)
plot(xx2, yy2, xlim = c(14, 36), ylim = c(0, 14000),type ="n" , axes = F, xlab ="", ylab ="",col="blue",main="")
lines(xx2, yy2, lwd = 2,col="red",lty=1)
points(xx2, yy2, pch = 18, cex = 1,col="red")
text(xx2, yy2 + 4 , labels = as.character(yy2),srt=90)
par(new = T)
par(mai = c ( 1 , 1, 1, 1))
axis(2)
mtext(2,text="",line=2.5)
mtext("",side=1,col="black",line=2)
grid()
It can be quote tricky to get things to line up if you use barplot and a standard plot(). I recommend only calling plot once. In order to do this, you will need to rescale your yy2 values to the same scale as yy. Here's how you might do that
par(mai = c ( 1 , 2, 1, 1), omi = c(0, 0, 0, 0))
yy <- c(31,31,31,50,50,61,69,75,80,88,94,101,108,115,121,124,125,125,125,126,127)
name1 <- c ("15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35")
#draw bar plot
xx <- barplot(yy, ylab = "", names.arg = name1, ylim = c(0, 140),col="steelblue")
text(xx, yy + 3, labels = as.character(yy),srt=45)
mtext(2,text="",line=2)
xx2 <- xx #c(15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35)
yy2 <- c(379,474,579,725,922,1181,1473,1846,2316,2962,3688,4786,6069,7605,9504,10680,11074,11074,11074,11483,11484)
#transform data
yy2tx <- yy2/14000 * max(pretty(yy))
#draw line data
lines(xx2, yy2tx, lwd = 2,col="red",lty=1)
points(xx2, yy2tx, pch = 18, cex = 1,col="red")
text(xx2, yy2tx, labels = as.character(yy2),srt=90)
#draw axis for transformed data
par(mai = c ( 1 , 1, 1, 1))
axis(2, at=pretty(c(0,14000))/14000*max(pretty(yy)), labels=pretty(c(0,14000)))
grid()
This produces the following plot
The problem is that you have different x scale due to the different margins of the two plots.
Unless you want to find xx2 by hand... another solution to consider is to use a right y axis instead.
yy <- c(31,31,31,50,50,61,69,75,80,88,94,101,108,115,121,124,125,125,125,126,127)
name1 <- c ("15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35")
xx <- barplot(yy, ylab = "", names.arg = name1, ylim = c(0, 140),col="steelblue")
text(xx, yy + 3, labels = as.character(yy),srt=45)
mtext(2,text="",line=2)
par(new = T)
yy2 <- c(379,474,579,725,922,1181,1473,1846,2316,2962,3688,4786,6069,7605,9504,10680,11074,11074,11074,11483,11484)
plot(xx+0.5, yy2, "l", lwd = 2,col="red",lty=1,
axes=F, ylim=c(0, 14000), xlim=c(min(xx), max(xx)+1))
points(xx+0.5, yy2, pch = 18, cex = 1,col="red")
axis(4)
text(xx+0.5, yy2 + 4 , labels = as.character(yy2),srt=90)
I would like to write a plot function for my specific purposes and put the y labels on the left margin. The length of these labels, however, can differ dramatically and depends on the model terms the user comes up with. For this reason, I would like to measure the width of the longest label and set the left margin width accordingly. I found the strwidth function, but I don't understand how to convert its output unit to the unit of the mar argument. An example:
label <- paste(letters, collapse = " ") # create a long label
par(mar = c(5, 17, 4, 2) + 0.1) # 17 is the left margin width
plot(1:2, axes = FALSE, type = "n") # stupid plot example
# if we now draw the axis label, 17 seems to be a good value:
axis(side = 2, at = 1, labels = label, las = 2, tck = 0, lty = 0)
# however, strwidth returns 0.59, which is much less...
lab.width <- strwidth(label) # so how can I convert the units?
You can use mai instead of mar to specify a distance in inches
(instead of "lines").
par(mai = c(1, strwidth(label, units="inches")+.25, .8, .2))
plot(1:2, axes=FALSE)
axis(side = 2, at = 1, labels = label, las = 2, tck = 0, lty = 0)
You can compute the conversion factor between lines and inches
by dividing mar by mai.
inches_to_lines <- ( par("mar") / par("mai") )[1] # 5
lab.width <- strwidth(label, units="inches") * inches_to_lines
par(mar = c(5, 1 + lab.width, 4, 2) + 0.1)
plot(1:2, axes=FALSE)
axis(side = 2, at = 1, labels = label, las = 2, tck = 0, lty = 0)
I made a graph in which a barplot and a line plot are combined. The problem is that the scale of my secondary y-axis isn't how it should be.
This is the code I used:
barplot <- barplot(covpatient[[1]]$cov, names.arg = covpatient[[1]]$exon, xlab = covpatient[[1]]$gene[1] , ylab = "read depth" , border = gray.colors(length(unique(covpatient[[1]]$exon)))[as.factor(covpatient[[1]]$exon)])
par(new = TRUE)
lines(x = barplot, y = covpatient[[1]]$amplicon, bty = "n")
axis(side = 4, at = pretty(range(covpatient[[1]]$amplicon)))
And this is how my plot looks like:
The values of the lines plot are OK, but you see that the y-axis is not fully expanded. I want it to look the same as the y-axis on the left
Can someone help me with this?
Without a reproducible example and a clear question all answers will at best be gueswork but have a look at the following:
x <- 1:10
y <- c(1, 3, 5, 6, 2, 7, 11, 3, 2, 13)
z <- runif(10, min=1000, max=10000)
par(mar = c(5, 4, 4, 4) + 0.3)
barplot(y, col=rainbow(length(x)))
par(new = TRUE)
plot(x, z, type = "l", axes = FALSE, bty = "n", xlab = "", ylab = "")
axis(side=4, at = pretty(range(z)))
mtext("z", side=4, line=3)
library(plotrix)
twoord.plot(x,y,x,z,
xlab="x",
ylab="y",
rylab="z",
main="Main",
type=c("bar","l"),lcol=rainbow(length(x)),rcol=4)