Align x-axis to plot for consistent use with grid - r

I'm trying to build an histogram using data available from here. I'm using using the CSV version of this database to display the number of exoplantes discovered per year. A simple script would be
bulkdata <- read.csv('file.csv',head=1,sep=',')
pdf(file="yearcount.pdf",family="Times")
bins <- seq(min(bulkdata$discovered,na.rm=T),max(bulkdata$discovered,na.rm=T),by=1)
hist(bulkdata$discovered,breaks=bins,col='gray',ylab="Discovered",xlab="Year",main="",ylim=c(0,100),axes=FALSE)
axis(1, at=seq(1989,2012,by=1))
axis(2, at=seq(0,100,by=10))
grid(nx=10)
hist(bulkdata$discovered,breaks=bins,col='gray',ylab="Discovered",xlab="Year",main="", add=TRUE)
dev.off()
The problem is that the xaxis is not aligned with the 0 point of the yaxis. This is a problem because the lines drawn by grid() does not mean anything because they are not aligned with the ticks! I tried to add in axis(1, at=seq(1989,2012,by=1)) the option line=-1 to correct but this way the axis is correctly drawn but the grid start below the axis. Maybe a non standard package is needed?

?grid says:
If more fine tuning is required, use ‘abline(h = ., v = .)’
directly.
So here's a suggestion:
par(las=1,bty="l")
h <- hist(bulkdata$discovered,breaks=bins,
col='gray',ylab="Discovered",xlab="Year",main="",
ylim=c(0,100),axes=FALSE)
yrs <- 1989:2012
yvals <- seq(0,100,by=10)
axis(1, at=yrs)
axis(2, at=yvals)
abline(h=yvals,v=yrs,col="gray",lty=3)
hist(bulkdata$discovered,breaks=bins,
col='gray',ylab="Discovered",xlab="Year",main="", add=TRUE)
I would consider making the grid lines a little bit sparser (e.g. every 5 years?)

Related

plot without border (like hist) in r

If you call function hist on r, you will note that the box that usually surrounds plotting region doesn't appear, instead, only rulers indicating plot scale appear on the bottom and on the left. If you use r a lot you may probably have noticed this already. my question is: there is some graphical parameter or workaround to make this happen on any other plot of basic r (like in a scatterplot, a line plot, a qq plot or whatever)?
The only parameter I found was axes, but setting it to FALSE makes it disappear not only the box, but also the rulers.
You are looking for box().
op <- par(mfrow=c(1, 2))
hist(mtcars$mpg, sub="w/o box")
hist(mtcars$mpg, sub="w/ box")
box() ## <-- this
par(op)
the answer is bty graphical parameter:
x= matrix(rnorm(100), ncol= 2)
plot(x, bty= 'n')

Multiple Pen's Parade Graphs on the same Plot

I'm doing stochastic dominance analysis with diferent income distributions using Pen's Parade. I can plot a single Pen's Parade using Pen function from ineq package, but I need a visual comparison and I want multiple lines in the same image. I don't know how extract values from the function, so I can't do this.
I have the following reproducible example:
set.seed(123)
x <- rnorm(100)
y <- rnorm(100, mean = 0.2)
library(ineq)
Pen(x)
Pen(y)
I obtain the following plots:
I want obtain sometime as the following:
You can use add = TRUE:
set.seed(123)
x <- rnorm(100)
y <- rnorm(100, mean = 0.2)
library(ineq)
Pen(x); Pen(y, add = TRUE)
From help("Pen"):
add logical. Should the plot be added to an existing plot?
While the solution mentioned by M-M in the comments is a more general solution, in this specific case it produces a busy Y axis:
Pen(x)
par(new = TRUE)
Pen(y)
I would generalize the advice for plotting functions in this way:
Check the plotting function's help file. If it has an add argument, use that.
Otherwise, use the par(new = TRUE) technique
Update
As M-M helpfully mentions in the comments, their more general solution will not produce a busy Y axis if you manually suppress the Y axis on the second plot:
Pen(x)
par(new = TRUE)
Pen(y, yaxt = "n")
Looking at ?ineq::Pen() it seems to work like plot(); therefore, followings work for you.
Pen(x)
Pen(y, add=T)
Note: However, add=T cuts out part of your data since second plot has points which fall out of the limit of the first.
Update on using par(new=T):
Using par(new=T) basically means overlaying two plots on top of each other; hence, it is important to make them with the same scale. We can achieve that by setting the same axis limits. That said, while using add=T argument it is desired to set limits of the axis to not loose any part of data. This is the best practice for overlaying two plots.
Pen(x, ylim=c(0,38), xlim=c(0,1))
par(new=T)
Pen(y, col="red", ylim=c(0,38), xlim=c(0,1), yaxt='n', xaxt='n')
Essentially, you can do the same with add=T.

Using skipRedraw in R {rgl} when rotating plot3d

I am not an R pro, self-taught- thank you for your help!
I have figured out the following code to my satisfaction, which gives me a 3d plot of my data and I can automatically rotate it. However, I want to stop the automatic redraw of the axes as it spins. I have found many resources using par3d(skipRedraw=TRUE) but I cannot figure out how to incorporate it into my code, it is all a bit beyond me.
Also, (I was going to give up on this one but since I'm asking anyway) I'd also like to be able to have the axes labels stay next to the axis tick marks (rather than across from it/on the other side). But this is secondary.
Thank you in advance!
mydata<-read.csv(file=file.choose(),header=TRUE,row.names=1)
mydata$Colour<-factor(mydata$ColourB,levels=c("Black","Blue","Red","Green","Yellow","Purple","Brown"))
colourb<-as.character(mydata$ColourB)
library(rgl)
open3d()
plot3d(mydata[,"Sr"],
mydata[,"Rb"],
mydata[,"Zr"],
xlab="Sr (ppm)",
ylab="Rb (ppm)",
zlab="Zr (ppm)",
pch=21,
col=colourb,
type="s",
radius=10
)
bgplot3d({
plot.new()
title(main = 'Trace Elements', line = 1)
})
play3d(spin3d(axis=c(0,0,1), rpm=10), duration=10)
It is easy to stop the automatic redraw of the axes. When you use bbox-axes (default), they are redrawn. So you just use fixed position axes. (EDITED: I might misunderstand your quiestion.)
Here is my example (using data trees):
open3d()
plot3d(trees, type="s", radius=0.4, col="red", xlab="xxx", ylab="yyy", zlab="zzz",
axes=F) # not use bbox-axes
axes3d(edges = c("x","y","z")) # draw fixed position axes
box3d() # if you need, draw full box
bgplot3d({
plot.new()
title(main = 'Trees', line = 1)
})
play3d(spin3d(axis=c(0,0,1), rpm=10), duration=10)
# PS: skipRedraw isn't what you think.
plot3d(trees)
par3d(skipRedraw = T) # you can't turn the graph by drag

asp is producing unnecessary whitespace within the axes of my R plot. How can I reformat the graph?

I'm trying to create a scatter plot + linear regression line in R 3.0.3. I originally tried to create it with the following simple call to plot:
plot(hops$average.temperature, hops$percent.alpha.acids)
This created this first plot:
As you can see, the scales of the Y and X axes differ. I tried fixing this using the asp parameter, as follows:
plot(hops$average.temperature, hops$percent.alpha.acids, asp=1, xaxp=c(13,18,5))
This produced this second plot:
Unfortunately, setting asp to 1 appears to have compressed the X axis while using the same amount of space, leaving large areas of unused whitespace on either side of the data. I tried using xlim to constrain the size of the X-axis, but asp seemed to overrule it as it didn't have any effect on the plot.
plot(hops$average.temperature, hops$percent.alpha.acids, xlim=c(13,18), asp=1, xaxp=c(13,18,5))
Any suggestions as to how I could get the axes to be on the same scale without creating large amounts of whitespace?
Thanks!
One solution would be to use par parameter pty and set it to "s". See ?par:
pty
A character specifying the type of plot region to be used; "s"
generates a square plotting region and "m" generates the maximal
plotting region.
It forces the plot to be square (thus conteracting the side effect of asp).
hops <- data.frame(a=runif(100,13,18),b=runif(100,2,6))
par(pty="s")
plot(hops$a,hops$b,asp=1)
I agree with plannapus that the issue is with your plotting area. You can also fix this within the device size itself by ensuring that you plot to a square region. The example below opens a plotting device with square dimension; then the margins are also set to maintain these proportions:
Example:
n <- 20
x <- runif(n, 13, 18)
y <- runif(n, 2, 6)
png("plot.png", width=5, height=5, units="in", res=200)
par(mar=c(5,5,1,1))
plot(x, y, asp=1)
dev.off()

R: Creating graphs with two y-axes

I'm looking to display two graphs on the same plot in R where the two graphs have vastly different scales i.e. the one goes from -0.001 to 0.0001 and the other goes from 0.05 to 0.2.
I've found this link http://www.statmethods.net/advgraphs/axes.html
which indicates how to display two y axes on the same plot, but I'm having trouble.
My code reads as follows:
plot(rateOfChangeMS[,1],type="l",ylim=c(-0.01,.2),axes = F)
lines(ratios[,1])
x = seq(-0.001,0.0001,0.0001)
x2 = seq(0.05,0.2,0.01)
axis(2,x)
axis(4,x2)
The problem I'm having is that, although R shows both axes, they are not next to each other as I would like, with the resulting graph attached. The left axis is measuring the graph with the small range, while the right is measuring the graph from 0.05 to 0.2. The second graph is, in fact, on the plot, but the scaling is so small that you can't see it.
Not sure if there is some etiquette rule I'm violating, never uploaded an image before so not quite sure how best to do it.
Any help would be greatly appreciated!
Thanks
Mike
Since you don't provide a reproducible example, or a representative dataset, this is a partial answer.
set.seed(1)
df <- data.frame(x=1:100,
y1=-0.001+0.002/(1:100)+rnorm(100,0,5e-5),
y2=0.05+0.0015*(0:99)+rnorm(100,0,1e-2))
ticks.1 <- seq(-0.001,0.001,0.0001)
ticks.2 <- seq(0.05,0.2,0.01)
plot(df$x, df$y1, type="l", yaxt="n", xlab="X", ylab="", col="blue")
axis(2, at=ticks.1, col.ticks="blue", col.axis="blue")
par(new=T)
plot(df$x, df$y2, type="l", yaxt="n", xlab="", ylab="", col="red")
axis(4, at=ticks.2, col.ticks="red", col.axis="red")
The reason your left axis is compressed is that both axes are on the same scale. You can get around that by basically superimposing two completely different plots (which is what having two axes does, after all). Incidentally, dual axes like this is not a good way to visualize data. It creates a grossly misleading visual impression.

Resources