I am trying to create a boxplot in R, however, I find that the figure has wrong tick values for the y-axis.
The .rdata is available at https://www.dropbox.com/s/vbgf3mhgd2mjx8o/Mydata2.rdata?dl=0
load("Mydata2.rdata",.GlobalEnv)
boxplot(Value~Type+Level, data=Mydata2)
As the figure shows, the y-axis is marked "0, 50, 100", however, my data range from -36.9 to 133.7. I wonder how to fix this?
Here, I used min, mean, and max for the tick marks. You can set them to any value manually or even have more than 3 ticks. yaxt="n" prevents the default tick marks and then by using axis and setting the side to 2 (axis(2,...) I add my desired tick marks. Read about ?axis in R.
boxplot(Value~Type+Level, yaxt="n", data=Mydata2)
axis(2,
at=round(c(min(Mydata2$Value), mean(Mydata2$Value), max(Mydata2$Value)),1),
labels = T)
Follow up question: How the default tick marks are computed?
"When at = NULL, pretty tick mark locations are computed internally (the same way axTicks(side) would)."
So, your code is working. Default tick marks are picked by boxplot so it is prettier (well pretty is subjective).
Two methods:
Set each tickmark individually via axis's at argument (at is a numeric vector defining each tickmark):
boxplot(Value~Type+Level, yaxt="n", data=Mydata2)
tickmarks = c(min(Mydata2$Value), max(Mydata2$Value))
axis(2, at = round(tickmarks,1))
Define the range for your tickmarks via boxplot's ylim argument. So, to set the range for your tickmarks between -40 and 140:
boxplot(Value~Type+Level, data=Mydata2, ylim=c(-40,140))
Method #2 works sometimes but not always. Method #1 is more reliable and customizable and should therefore be used more often.
I would like to draw X and Y axis in the beggining of the system of equations, but i don't know how. When i'm trying to set axis it always putting them under the plotted function.
pi=3.141592
x= seq(-pi,pi,0.1)
plot(x,sin(x), axes=FALSE)
axis (1,-3:3)
I don't wanna put simple lines, because i wanna have values in those axis, and would like to change those values.
Alright!
I get it, to draw Y axis in 0 position i need to add
axis(4, labels=TRUE, pos=0)
after plotting, thanks buddy!
No problem!
I have a problem with the x-axis labelling.
I created a lm model(first.stage) and plotted the residuals using the code:
plot(first.stage$residuals,ylab="Deviation",xlab="Year",type="l",col="blue")
Now I'd like to change the x-axis labelling independent from the x values.
More precisely, I want to show the years 1960-2010 on the x axis. I tried a lot nothing worked.
If you want to set custom tick marks for your x axis, set xaxt = 'n' in the plot() call, then use axis(1, at = c()) to set the new tick marks. For example,
plot(mtcars$wt, mtcars$mpg, xaxt='n')
axis(1, at = c(1.5, 2.5))
When I manually add the following labels with (axis(1, at=1:27, labels=labs[0:27])):
> labs[0:27]
[1] "0\n9.3%" "1\n7.6%" "2\n5.6%" "3\n5.1%" "4\n5.7%" "5\n6.5%" "6\n7.3%" "7\n7.6%" "8\n7.5%" "9\n7%" "10\n6.2%" "11\n5.2%"
[13] "12\n4.2%" ........
I get the following:
How do I force all labels to be drawn so 1,3,5,6, and 11 are not skipped? (also, for extra credit, how do I shift the whole thing down a few pixels?)
If you want to force all labels to display, even when they are very close or overlapping, you can "trick" R into displaying them by adding odd and even axis labels with separate calls to the axis function, as follows:
labs <-c("0\n9.3%","1\n7.6%","2\n5.6%","3\n5.1%","4\n5.7%","5\n6.5%","6\n7.3%",
"7\n7.6%","8\n7.5%","9\n7%", "10\n6.2%","11\n5.2%","12\n4.2%",13:27)
n=length(labs)
plot(1:28, xaxt = "n")
axis(side=1, at=seq(1,n,2), labels=labs[seq(1,n,2)], cex.axis=0.6)
axis(side=1, at=seq(2,n,2), labels=labs[seq(2,n,2)], cex.axis=0.6)
You can play with cex.axis to get the text size that you want. Note, also, that you may have to adjust the number of values in at= and/or labels= so that they are equal.
I agree with #PLapointe and #joran that it's generally better not to tamper with R's default behavior regarding overlap. However, I've had a few cases where axis labels looked fine even when they weren't quite a full "m-width" apart, and I hit on the trick of alternating odd and even labels as a way to get the behavior I wanted.
?axis tells you that:
The code tries hard not to draw overlapping tick labels, and so will omit labels where they would abut or overlap previously drawn labels. This can result in, for example, every other tick being labelled. (The ticks are drawn left to right or bottom to top, and space at least the size of an ‘m’ is left between labels.)
Play with cex.axis so that labels are small enough to fit without overlapping
labs <-c("0\n9.3%","1\n7.6%","2\n5.6%","3\n5.1%","4\n5.7%","5\n6.5%","6\n7.3%",
"7\n7.6%","8\n7.5%","9\n7%", "10\n6.2%","11\n5.2%","12\n4.2%",12:27)
plot(1:27,xaxt = "n")
axis(side=1, at=1:27, labels=labs[0:27],cex.axis=0.35)
If you widen you graph (manually by dragging or programmatically), you can increase the size of your labels.
Although there are some good answers here, the OP didn't want to resize the labels or change anything about the plot besides fitting all of the axis labels. It's annoying, since often there appears to be plenty of room to fit all of the axis labels.
Here's another solution. Draw the plot without the axis, then add ticks with empty labels. Store the positions of the ticks in an object, so then you can go through each one and place it in the correct position on the axis.
plot(1:10, 1:10, yaxt = "n")
axis_ticks = axis(2, axTicks(2), labels = rep("", length(axTicks(2))))
for(i in axis_ticks) axis(2, i)
#PLapointe just posted what I was going to say, but omitted the bonus answer.
Set padj = 0.5 in axis to move the labels down slightly.
Perhaps draw and label one tick at a time, by calling axis repeatedly using mapply...
For example, consider the following data:
x = runif(100)*20
y = 10^(runif(100)*3)
The formula for y might look a bit odd; it gives random numbers distributed across three orders of magnitude such that the data will be evenly distributed on a plot where the y axis is on a log scale. This will help demonstrate the utility of axTicks() by calculating nice tick locations for us on a logged axis.
By default:
plot(x, y, log = "y")
returns:
Notice that 100 and 1000 labels are missing.
We can instead use:
plot(x, y, log = "y", yaxt = "n")
mapply(axis, side = 2, at = axTicks(2), labels = axTicks(2))
which calls axis() once for each tick location returned by axTicks(), thus plotting one tick at a time. The result:
What I like about this solution is that is uses only one line of code for drawing the axis, it prints exactly the default axis R would have made, except all ticks are labeled, and the labels don't go anywhere when the plot is resized:
I can't say the axis is useful in the resized example, but it makes the point about axis labels being permanent!
For the first (default) plot, note that R will recalculate tick locations when resizing.
For the second (always labeled) plot, the number and location of tick marks are not recalculated when the image is resized. The axis ticks calculated by axTicks depend upon the size of the display window when the plot is first drawn.
If you want want to force specific tick locations, try something like:
plot(x, y, log = "y", yaxt = "n")
mapply(axis, side = 2, at = c(1,10,100, 1000), labels = c("one", "ten", "hundred", "thousand"))
which yields:
axis() includes a gap.axis parameter that controls when labels are omitted. Setting this to a very negative number will force all labels to display, even if they overlap.
The padj parameter of axis() controls the y offset whilst plotting an individual axis.
par(mgp = c(3, 2, 0) will adjust the position of all axis labels for the duration of a plotting session: the second value (here 2, default 1) controls the position of the labels.
# Set axis text position, including for Y axis
par(mgp = c(3, 2, 0))
# Plot
plot(1:12, 1:12, log = 'x', ann = FALSE, axes = FALSE)
# Some numbers not plotted:
axis(1, 1:12)
# All numbers plotted, with manual offset
axis(1, 1:12, gap.axis = -100, padj = 0.5)
I had a similar problem where I wanted to stagger the labels and get them to print without losing some. I created two sets of ticks showing second set below the other to make it look as if it staggers.
xaxis_stagger = function(positions,labels) {
odd=labels[seq(1,length(labels),2)]
odd_pos=positions[seq(1,length(positions),2)]
even=labels[seq(2,length(labels),2)]
even_pos=positions[seq(2,length(positions),2)]
axis(side=1,at=odd_pos,labels=odd)
axis(side=1,at=even_pos,labels=even,padj=1.5)
}
So you give the positions where you want the ticks to be and the labels for those ticks and this would then re-organise it into two sets of axis and plot them on the original plot. Original plot would be done with xaxt="n".
I have a data set containing names of Solar Panel arrays, their dates of completion and location (long/lat).
I created an rplot with the time of completion on the x axis and the names of each array on the y axis.
Here in lies the problem - the actual names are not displayed but the number designation for each row is. Is there a way to get the names listed on the y axis instead of the numbers?
![Names are supposed to show on the y axis, the years show up fine on the x axis]
Heres the code I used to make my rplot:
plot(solar$Year.completed, solar$Name, xlim=c(1990, 2025))
I am also considering making adding more granularity (if that's even a word to the x axis)
Thanks to whomever can help with this.
Here is what the plot looks like:
Yup as everyone says, it's a lot easier if you can include data. But probably what you want is this:
plot(solar$Year.completed, solar$Name, xlim=c(1990, 2025), yaxt="n")
axis(2, at=1:length(unique(solar$Name)), labels=unique(solar$Name), cex.axis=0.5, las=2)
in the first line, yaxt="n" gets rid of the default y axis labels
the second line creates a series of points for each unique value of solar$Name
2 (first argument) means it's the y axis
cex.axis reduces the font size (because it looks like you have a lot of points)
las-2 makes the labels perpendicular (again you probably need the space)
and if you want granularity on the x-axis, you can do something similar (i.e. add xaxt="n" and create a custom x axis:
plot(solar$Year.completed, solar$Name, xlim=c(1990, 2025), yaxt="n", xaxt="n")
axis(2, at=1:length(unique(solar$Name)), labels=unique(solar$Name), cex.axis=0.5, las=2)
axis(1, at=1990:2025, labels=1990:2025, cex.axis=0.7, las=2)