I'm trying to use R to do a barplot. Values I'm plotting range from 0 to 5.0, but are decimal values (such as 4.87) so I don't want to just use the default Y axis, because it just goes up in increments of 1.
I've created a custom Y axis, which works, but if I set the maximum value greater than about 4.5, it cuts off the tickmark at the top of the axis. This looks untidy so I want a way to ensure this tickmark will always appear, but I don't want to shorten my axis as it looks stupid if I do this.
My R code is as follows:
# Bar plot of mean SUS question scores
barplot(meanSUSQuestions$Mean,
main="Mean SUS Question Scores",
cex.main="0.8",
cex.axis="0.8",
cex.lab="0.8",
#names=c("q1", "q2", "q3","q4","q5","q6","q7","q8","q9","q10"),
names=c(1:10),
yaxt="n",
col="red")
axis(2, cex.axis="0.8", at=seq(0, 5, 0.5)) # Create custom Y axis
mtext(text="Mean Score", side=2, line=2, cex=0.8)
mtext(text="Question", side=1, line=2, cex=0.8)
The bar plot that this produces looks like this:
As you can see from the picture, the top tickmark is missing.
How can I get this top tickmark to appear?
barplot generates the image height based on the data. The range of your manual y-axis is considerably larger than the plot area and is thus cut off.
The easiest way to solve the issue in your specific case is to add an yaxp = c(0, 5, 11) to barplot instead of yaxt = "n" and axis.
A self-contained example:
# Bad
x <- 1:5
barplot(x, yaxt = "n") #, add = TRUE)
axis(2, at = seq(0, 6, 2)) # Create custom Y axis
# Good
barplot(x, yaxp = c(0, 6, 2))
Related
I would like to make my y axis labels horizontal, while keeping my y axis titles as parallel.
When I try inputting las=1 into the twoor.plot()argument, nothing happens. I have also tried ylas=1, y_las=1, lylas=1, rylas=1, and nothing happens. The only way I've been able to make my yaxis labels horizontal, is by using par(las=1), but then this makes my y-axis titles horizontal too, which I don't want...
This is my code so far:
par(las=1)
yFrequency <- c(0,20,40,60,80,100,120,140,160)
GS_class_labels <- c("<2", "2-4", "4-8", "8-16", "16-32", "32-64", "64-128", "128<")
twoord.plot(data=distribution,lx="Var1",ly="Freq", ry="cum_percentile",
main="B1 Surface Grain Size Distribution",
xlim=NULL,lylim=c(0,160),rylim=NULL,lwd=1.5,
lcol=1,rcol=2,xlab="Grain Size (mm)",lytickpos=yFrequency,
ylab="Frequency",ylab.at=NA,
rytickpos=NA,rylab="Percent Finer Than (%)",rylab.at=NA,
lpch=1,rpch=2,
type="b",xtickpos=NULL,xticklab=GS_class_labels,
halfwidth=0.4,axislab.cex=1.1,
do.first=NULL,xaxt="s", yticklab=yFrequency, cex.lab=1)
An alternative way to set the y axis labels parallel is as follows.
(1) Set both of the ylab and rylab from twoord.plot to empty.
(2) Use mtext and set the parameters accordingly.
Here is the code to do that. Because you don't provide the distribution data, I use iris data just to make it possible to generate the plot.
# Emptying both of ylab and rylab
twoord.plot(data = iris,lx="Sepal.Length",ly="Petal.Width", ry="Sepal.Width",
main="B1 Surface Grain Size Distribution",
xlim=NULL,lylim=c(0,160),rylim=NULL,lwd=1.5,
lcol=1,rcol=2,xlab="Grain Size (mm)",lytickpos=yFrequency,
ylab="",ylab.at=NA,
rytickpos=NA,rylab="",rylab.at=NA,
lpch=1,rpch=2,
type="b",xtickpos=NULL,xticklab=GS_class_labels,
halfwidth=0.4,axislab.cex=1.1,
do.first=NULL,xaxt="n",yaxt="n", #yticklab=yFrequency,
cex.lab=1)
# Assign the previous labels of ylab and rylab to the *text* parameter of *mtext*.
# side = 2 means the left side. side = 4 means the right side.
# las = 0 is the parallel style of the text.
# line shows the distance of the text from the y axis.
mtext(text = "Frequency", side = 2, las = 0, line = 2.5)
mtext(text = "Percent Finer Than (%)", side = 4, las = 0, line = 0.5)
The resulted plot:
Is it possible to increase the values in the X-axis with 1? For example - 1,2,3,4,5 etc.
Right now I use this:
xlim=c(1,16)
And the result is:
Which doesn't look nice, the ideal would be to have a sequential increase with 1 - from 1 to 16, since I have 16 values for the X-axis.
xlim can be finely controlled with axis. To make it clear, I will reproduce one plot without axis control and one instead where we performed a modification on the scale.
x <- rnorm(100, 10, 2)
y <- rnorm(100, 10, 2)
par(mfrow = c(1, 2))
Plot 1 is produced without axis control
plot(x, y, main = "Plot 1")
In Plot 2 we set a demonstrative xlim and ylim that produce a scale from 0 to 20 for both axes. We can more finely tune it with axis: to make an example, I create a scale by 1 for axis x and by 5 for axis y
plot(x, y, xlim = c(0, 20), ylim = c(0, 20), main = "Plot 2")
axis(1, at=seq(0, 20, 1))
axis(2, at=seq(0, 20, 5))
That's not all. axis allow a really fine work on your plot axis with its arguments.
axis(side, at=, labels=, pos=, lty=, col=, las=, tck=, ...)
side
an integer indicating the side of the graph to draw the axis (1=bottom, 2=left, 3=top, 4=right)
at
a numeric vector indicating where tic marks should be drawn
labels
a character vector of labels to be placed at the tickmarks (if NULL, the at values will be used)
pos
the coordinate at which the axis line is to be drawn. (i.e., the value on the other axis where it crosses)
lty
line type
col
the line and tick mark color
las
labels are parallel (=0) or perpendicular(=2) to axis
tck
length of tick mark as fraction of plotting region (negative number is
outside graph, positive number is inside, 0 suppresses ticks, 1 creates gridlines) default is -0.01
I have this code:
# Plotting everything
plot( p1, col= "lightgreen", xlim=c(-2.5,4.5), ylim=c(0, 700), main="Daily Total Precipitation for AR and Oct-May", xlab="ln(x)" , ylab="Frequency", xaxt = "n") # first histogram
plot( p2, col="red", xlim=c(-2.5,4.5), ylim=c(0, 700), xaxt = "n" , add=T)
# Adding in text labels on top of the bars
text(x, y, paste(round(percents,2),"%"), cex=0.50, pos=3, offset=0.3, col="black")
axis(side=1, at=breaks) # new x-axis
# parameter that needs to be set to add a new graph on top of the other ones
par(new=T)
plot(x, percents, xlim=c(-2.5,4.5), type="l", col="yellow", lwd=3.0, axes=F, ylab=NA, xlab=NA)
axis(side=4, at=seq(0,100,by=10), col="yellow", col.axis="yellow") # additional y-axis
mtext("Percent", side=4, col="yellow")
# legend settings
legend("topleft", c("AR", "Oct-May"), lwd=10, col=c("red", "lightgreen"))
Which produces this graph:
And I can't seem to figure out how to get the secondary y-axis label to show up in the correct position. Any help or suggestions is greatly appreciated.
Edit: Using RStudio.
One option is to specify the line argument to mtext(). In the example below I add a couple more lines to the right (side = 4) margin of the plot using par(), and then I draw three labels using mtext() at the default (line = 0), line 3 (line = 3), and line -3 (line = -3):
op <- par(mar = c(5,4,4,4) + 0.1)
plot(1:10)
mtext("line0", side = 4)
mtext("line3", side = 4, line = 3)
mtext("line-3", side = 4, line = -3)
par(op)
Note that line numbers increase away from the plot region and that negative line values move into the plot region, or to the left of the right boundary of the plot region.
It takes a little playing with the number of margin lines (as set in par(mar = x)) and which line you want to draw on using mtext(), but a little trial and error should get you what you want.
Note also that you don't need to specify integer values for the line argument. You can specify fractions of lines too: line = 2.5.
How can I increase the length of plot tick marks? Here is a small example:
r <- as.POSIXct(round(range(time), "mins"))
plot(time, x, t="l", xaxt = "n")
axis.POSIXct(1, at = seq(r[1], r[2], by = "min"), format = "%H:%M:%S")
which gives
As you can see, all the ticks are the same size. Is there a way to automatically increase the length of those ticks that are signed?
When creating a very specific axis layout, you typically need to add the axis after drawing the plot. Since you didn't have a reproducible example, I've created my own data set.
Create a plot, but don't display the axis
plot(1:10, axes=FALSE, frame=TRUE)
Add in the x-scale. In this example, values 1,2,3, ...., 10. The argument tck specifies the tick length:
##The tck value should be smaller here
axis(1, 1:10, tck=-0.05)
Now add in an additional scale for "in-between" values. I've set labels="", so we don't print any values:
axis(1, seq(0.5, 9.5, 1), labels=rep("", 10), tck=-0.01)
This gives:
I used this code to make this plot:
plot(p, cv2,col=rgb(0,100,0,50,maxColorValue=255),pch=16,
panel.last=abline(h=67,v=1.89, lty=1,lwd=3))
My plot looks like this:
1.) How can I plot the value of the ablines in a simple plot?
2.) How can I scale my plot so that both lines appear in the middle?
to change scale of plot so lines are in the middle change the axes i.e.
x<-1:10
y<-1:10
plot(x,y)
abline(a=1,b=0,v=1)
changed to:
x<-1:10
y<-1:10
plot(x,y,xlim=c(-30,30))
abline(a=1,b=0,v=1)
by "value" I am assuming you mean where the line cuts the x-axis? Something like text? i.e.:
text((0), min(y), "number", pos=2)
if you want the label on the x axis then try:
abline(a=1,b=0,v=1)
axis(1, at=1,labels=1)
to prevent overlap between labels you could remove the zero i.e.:
plot(x,y,xlim=c(-30,30),yaxt="n")
axis(2, at=c(1.77,5,10,15,20,25))
or before you plot extend the margins and add the labels further from the axis
par(mar = c(6.5, 6.5, 6.5, 6.5))
plot(x,y,xlim=c(-30,30))
abline(a=1,b=0,v=1)
axis(2, at=1.77,labels=1.77,mgp = c(10, 2, 0))
Similar in spirit to the answer proposed by #user1317221, here is my suggestion
# generate some fake points
x <- rnorm(100)
y <- rnorm(100)
# positions of the lines
vert = 0.5
horiz = 1.3
To display the lines at the center of the plot, first compute the horizontal and vertical distances between the data points and the lines, then adjust the limits adequately.
# compute the limits, in order for the lines to be centered
# REM we add a small fraction (here 10%) to leave some empty space,
# available to plot the values inside the frame (useful for one the solutions, see below)
xlim = vert + c(-1.1, 1.1) * max(abs(x-vert))
ylim = horiz + c(-1.1, 1.1) * max(abs(y-horiz))
# do the main plotting
plot(x, y, xlim=xlim, ylim=ylim)
abline(h=horiz, v=vert)
Now, you could plot the 'values of the lines', either on the axes (the lineparameter allows you to control for possible overlapping):
mtext(c(vert, horiz), side=c(1,2))
or alternatively within the plotting frame:
text(x=vert, y=ylim[1], labels=vert, adj=c(1.1,1), col='blue')
text(x=xlim[1], y=horiz, labels=horiz, adj=c(0.9,-0.1), col='blue')
HTH