Scale the y axis as power 10 values in R - r

I am trying to get only power 10 scale on the y axis, and I have tried many approaches offered on StackOverflow but none produce what I want.
I want to define the scale of y-axis to start from 10^2 and then next tick be at 10^4 and then on 10^6.
I have tried xaxt and at and axis and everything mentioned here, but none work for 10^x..

The plot.default() function provides a log argument which can be used to easily get a logarithmic scale of the x-axis, y-axis, or both. For example:
x <- 2:6;
y <- 10^x;
plot(x,y,log='y');
If you want to control the y-axis ticks, you can override the default axis and draw your own in the normal way:
## generate data
x <- 2:6;
y <- 10^x;
## precompute plot parameters
xlim <- c(2,6);
ylim <- c(10^2,10^6);
xticks <- 2:6;
yticks <- 10^seq(2L,6L,2L);
## draw plot
plot(NA,xlim=xlim,ylim=ylim,log='y',axes=F,xaxs='i',yaxs='i',xlab='x',ylab='y');
abline(v=xticks,col='lightgrey');
abline(h=yticks,col='lightgrey');
axis(1L,xticks,cex.axis=0.7);
axis(2L,yticks,sprintf('10^%d',as.integer(log10(yticks))),las=2L,cex.axis=0.7);
##axis(2L,yticks,sprintf('%.0e',yticks),las=2L,cex.axis=0.7); ## alternative
points(x,y,pch=19L,col='red',xpd=NA);

axis() works:
x <- 2:6
y <- 10 ^ x
plot(x, y, yaxt = "n")
axis(2, at = 10^(c(2, 4, 6)))
The only problem is that, this is certainly not a good way for presentation. Do you know how fast 1e+n grows?? As you have already seen in the plot, the ticks for 1e+2 and 1e+4 almost coincide, because 1e+6 is so big. If your data range from 1 ~ 1e+8 or even greater, then you'd better plot them on log scale.
plot(x, log10(y), yaxt = "n")
axis(2, at = c(2,4,6))

Related

How to make custom spacing for y-axis in R?

I want to make a plot in R where the spacing between ticks on the y-axis all have the same distance and the tick labels are a custom list of values, for example:
set.seed(1)
n <- 10
x <- 1:n
y <- rnorm(n)
plot(x, y, axes = FALSE, ylim=c(-2,2))
axis(1)
axis(2, seq(-2,2,1), c(-100,-10,0,5,1000))
gets me a plot where the distance between the y-axis ticks are equal but clearly the true distance between values is not equal, i.e., -100 to - 10 is not the same distance as 5 to 1000, numerically.
Now this works, but the problem with this solution is that the data is not correctly mapped to the right position in the plot. As in, I would like for the data to be plotted correctly based on the original scale. So either I need a way to simply change the y-axis to be plotted on a different scale, or for the data to be transformed to a new scale that matches my axis(2, seq(-2,2,1), c(-100,-10,0,5,1000)) command.
I guess what I am saying is I want the equivalent of plot(x, y, log = "y") but I don't actually want the log scale, I just want the tick marks to be even spaced based on values I want shown, i.e., -100,-10,0,5,1000
Your example is a bit hard to implement because you are setting the plot boundaries from -2 to 2 and then wanting axis labels that go from -100 to 1000. It should work if you use at and set the boundaries of the initial plot to match the axis parameters. I've modified your example to spread the data across the plot more evenly:
set.seed(1)
n <- 10
x <- 1:n
y <- 100*rnorm(n)
yticks = c(-100,-10,0,5,200)
plot(x, y, axes = FALSE, ylim=c(-100,200))
axis(1)
axis(2,at = yticks,labels=yticks)

R how to automatically adjust y axis when using basic plot with xlim

I'm trying to use base R (and would like to stick to it for this problem) to plot a specific portion of a dataset.
My example data looks like below:
x <- c(1:100)
y <- sort(runif(100, min=0, max=1000))
When I plot this with plot(x,y, type='l'), I get a plot with a y axis that shows 0 to 1000. However, when I plot only a specific x range, my y axis still shows 0 to 1000. I would like to zoom in to reduce the y axis range.
For example,
plot(x,y, type='l', xlim=c(40,60))
plot(x,y, type='l', xlim=c(80,90))
both produces plots with a y axis that ranges c(0,1000). But I'd like to zoom in so that the y axis range for the first plot is something like c(300,700) and that for the second plot is c(700,1000). (300, 700 and 1000 are all arbitrary numbers just to illustrate the purpose to really zoom into the plot). Is there a way to do this without setting specific ylim?
I'd like to avoid using ylim because I'm plotting and saving in a for loop and I can't write a ylim that is suitable for all plots. I've thought of doing something like ylim = max(y)*1.5, but again, since I'm cutting the y values off based on xlim, this doesn't help with zooming in whenever xlim changes.
Subset the relevant data and plot that
lower = 40
upper = 60
ind = which(x >= lower & x <= upper)
plot(x[ind], y[ind], type = "l")

How do I add custom ranges and points in the axes of a Base R plot?

Let's consider a vector and plot it.
s1 <- sample(100:1000,32,replace = T)
plot(s1)
The plot I get has a Y-Axis that ranges from 0-1000 with points in the intervals of 200 (0,200,400,600,800,1000) and this is happening implicitly.
If I use ylim argument, apparently or to be honest, evidently, I can now have a custom range,
plot(s1,ylim = c(0,1500))
The points on Y Axis now are 0-1500 as indicated but with the points in the intervals of 500 (0,500,1000,1500), this is happening without my control.
My question, how can I have custom points with custom intervals on the X or Y axis?
use axis() to set your limits : on either x, y, or both
s1 <- sample(100:1000,32,replace = T)
plot(s1, yaxt = "n") # `yaxt` prevents y-axis labels to be printed
axis(2, yaxp=c(10, 1000, 10), las=2) # 'las' helps to align the tick mark labels along the axis or perpendicular
# 'yaxp' helps to set the break points you desire. Learn more from ?par

How to remove e-notation on y axis when plotting graph with R? [duplicate]

I regularly do all kinds of scatter plots in R using the plot command.
Sometimes both, sometimes only one of the plot axes is labelled in scientific notation. I do not understand when R makes the decision to switch to scientific notation. Surprisingly, it often prints numbers which no sane human would write in scientific notation when labelling a plot, for example it labels 5 as 5e+00. Let's say you have a log-axis going up to 1000, scientific notation is unjustified with such "small" numbers.
I would like to suppress that behaviour, I always want R to display integer values. Is this possible?
I tried options(scipen=10) but then it starts writing 5.0 instead of 5, while on the other axis 5 is still 5 etc. How can I have pure integer values in my R plots?
I am using R 2.12.1 on Windows 7.
Use options(scipen=5) or some other high enough number. The scipen option determines how likely R is to switch to scientific notation, the higher the value the less likely it is to switch. Set the option before making your plot, if it still has scientific notation, set it to a higher number.
You can use format or formatC to, ahem, format your axis labels.
For whole numbers, try
x <- 10 ^ (1:10)
format(x, scientific = FALSE)
formatC(x, digits = 0, format = "f")
If the numbers are convertable to actual integers (i.e., not too big), you can also use
formatC(x, format = "d")
How you get the labels onto your axis depends upon the plotting system that you are using.
Try this. I purposely broke out various parts so you can move things around.
library(sfsmisc)
#Generate the data
x <- 1:100000
y <- 1:100000
#Setup the plot area
par(pty="m", plt=c(0.1, 1, 0.1, 1), omd=c(0.1,0.9,0.1,0.9))
#Plot a blank graph without completing the x or y axis
plot(x, y, type = "n", xaxt = "n", yaxt="n", xlab="", ylab="", log = "x", col="blue")
mtext(side=3, text="Test Plot", line=1.2, cex=1.5)
#Complete the x axis
eaxis(1, padj=-0.5, cex.axis=0.8)
mtext(side=1, text="x", line=2.5)
#Complete the y axis and add the grid
aty <- seq(par("yaxp")[1], par("yaxp")[2], (par("yaxp")[2] - par("yaxp")[1])/par("yaxp")[3])
axis(2, at=aty, labels=format(aty, scientific=FALSE), hadj=0.9, cex.axis=0.8, las=2)
mtext(side=2, text="y", line=4.5)
grid()
#Add the line last so it will be on top of the grid
lines(x, y, col="blue")
You can use the axis() command for that, eg :
x <- 1:100000
y <- 1:100000
marks <- c(0,20000,40000,60000,80000,100000)
plot(x,y,log="x",yaxt="n",type="l")
axis(2,at=marks,labels=marks)
gives :
EDIT : if you want to have all of them in the same format, you can use the solution of #Richie to get them :
x <- 1:100000
y <- 1:100000
format(y,scientific=FALSE)
plot(x,y,log="x",yaxt="n",type="l")
axis(2,at=marks,labels=format(marks,scientific=FALSE))
You could try lattice:
require(lattice)
x <- 1:100000
y <- 1:100000
xyplot(y~x, scales=list(x = list(log = 10)), type="l")
The R graphics package has the function axTicks that returns the tick locations of the ticks that the axis and plot functions would set automatically. The other answers given to this question define the tick locations manually which might not be convenient in some situations.
myTicks = axTicks(1)
axis(1, at = myTicks, labels = formatC(myTicks, format = 'd'))
A minimal example would be
plot(10^(0:10), 0:10, log = 'x', xaxt = 'n')
myTicks = axTicks(1)
axis(1, at = myTicks, labels = formatC(myTicks, format = 'd'))
There is also an log parameter in the axTicks function but in this situation it does not need to be set to get the proper logarithmic axis tick location.
Normally setting axis limit # max of your variable is enough
a <- c(0:1000000)
b <- c(0:1000000)
plot(a, b, ylim = c(0, max(b)))

Do not want scientific notation on plot axis

I regularly do all kinds of scatter plots in R using the plot command.
Sometimes both, sometimes only one of the plot axes is labelled in scientific notation. I do not understand when R makes the decision to switch to scientific notation. Surprisingly, it often prints numbers which no sane human would write in scientific notation when labelling a plot, for example it labels 5 as 5e+00. Let's say you have a log-axis going up to 1000, scientific notation is unjustified with such "small" numbers.
I would like to suppress that behaviour, I always want R to display integer values. Is this possible?
I tried options(scipen=10) but then it starts writing 5.0 instead of 5, while on the other axis 5 is still 5 etc. How can I have pure integer values in my R plots?
I am using R 2.12.1 on Windows 7.
Use options(scipen=5) or some other high enough number. The scipen option determines how likely R is to switch to scientific notation, the higher the value the less likely it is to switch. Set the option before making your plot, if it still has scientific notation, set it to a higher number.
You can use format or formatC to, ahem, format your axis labels.
For whole numbers, try
x <- 10 ^ (1:10)
format(x, scientific = FALSE)
formatC(x, digits = 0, format = "f")
If the numbers are convertable to actual integers (i.e., not too big), you can also use
formatC(x, format = "d")
How you get the labels onto your axis depends upon the plotting system that you are using.
Try this. I purposely broke out various parts so you can move things around.
library(sfsmisc)
#Generate the data
x <- 1:100000
y <- 1:100000
#Setup the plot area
par(pty="m", plt=c(0.1, 1, 0.1, 1), omd=c(0.1,0.9,0.1,0.9))
#Plot a blank graph without completing the x or y axis
plot(x, y, type = "n", xaxt = "n", yaxt="n", xlab="", ylab="", log = "x", col="blue")
mtext(side=3, text="Test Plot", line=1.2, cex=1.5)
#Complete the x axis
eaxis(1, padj=-0.5, cex.axis=0.8)
mtext(side=1, text="x", line=2.5)
#Complete the y axis and add the grid
aty <- seq(par("yaxp")[1], par("yaxp")[2], (par("yaxp")[2] - par("yaxp")[1])/par("yaxp")[3])
axis(2, at=aty, labels=format(aty, scientific=FALSE), hadj=0.9, cex.axis=0.8, las=2)
mtext(side=2, text="y", line=4.5)
grid()
#Add the line last so it will be on top of the grid
lines(x, y, col="blue")
You can use the axis() command for that, eg :
x <- 1:100000
y <- 1:100000
marks <- c(0,20000,40000,60000,80000,100000)
plot(x,y,log="x",yaxt="n",type="l")
axis(2,at=marks,labels=marks)
gives :
EDIT : if you want to have all of them in the same format, you can use the solution of #Richie to get them :
x <- 1:100000
y <- 1:100000
format(y,scientific=FALSE)
plot(x,y,log="x",yaxt="n",type="l")
axis(2,at=marks,labels=format(marks,scientific=FALSE))
You could try lattice:
require(lattice)
x <- 1:100000
y <- 1:100000
xyplot(y~x, scales=list(x = list(log = 10)), type="l")
The R graphics package has the function axTicks that returns the tick locations of the ticks that the axis and plot functions would set automatically. The other answers given to this question define the tick locations manually which might not be convenient in some situations.
myTicks = axTicks(1)
axis(1, at = myTicks, labels = formatC(myTicks, format = 'd'))
A minimal example would be
plot(10^(0:10), 0:10, log = 'x', xaxt = 'n')
myTicks = axTicks(1)
axis(1, at = myTicks, labels = formatC(myTicks, format = 'd'))
There is also an log parameter in the axTicks function but in this situation it does not need to be set to get the proper logarithmic axis tick location.
Normally setting axis limit # max of your variable is enough
a <- c(0:1000000)
b <- c(0:1000000)
plot(a, b, ylim = c(0, max(b)))

Resources