I like to produce my own grid lines when plotting so I can control tick marks, etc. and I am struggling with this with the \'hist\' plotting routine.
his
Actually, R has a way to do this! It's the panel.first
argument to plot.default
, which hist
calls to do most of the work. It takes an expression which is evaluated "after the plot axes are set up but before any plotting takes place. This can be useful for drawing background grids or scatterplot smooths," to quote from ?plot.default
.
hist(WindSpeed, breaks=c(0:31), freq=TRUE, col="blue", xaxt="n", yaxt="n",
xlab="Wind Speed (m/s)", main="Foo",
cex.main=1.5, cex.axis=1, cex.lab=1, tck=1, font.lab=2,
panel.first={
axis(1, tck=1, col.ticks="light gray")
axis(1, tck=-0.015, col.ticks="black")
axis(2, tck=1, col.ticks="light gray", lwd.ticks="1")
axis(2, tck=-0.015)
minor.tick(nx=5, ny=2, tick.ratio=0.5)
box()
})
See How do I draw gridlines using abline() that are behind the data? for another question that uses this method.
In R, order matters when you plot. As you've discovered, adding things to a plot adds on top of what you've plotted before. So we need a way to plot the grid first and then the histogram. Try something like this:
plot(1:10,1:10,type = "n")
grid(10,10)
hist(rnorm(100,5,1),add = TRUE)
I haven't recreated your example, since it isn't reproducible, but this general idea should work. But the key idea is to create an empty plot with the correct dimensions using the type = "n"
option to plot
, then add the grid, then add the histogram using the add = TRUE
argument.
Note that the add
argument is actually for plot.histogram
, hist
passes it along via ...
.
This is relatively easy.
Generate the histogram but don't plot it.
h <- hist(y, plot = FALSE)
Now generate your base plot... I've added some features to make it look more like a standard historgram
plot(h$mids, h$counts, ylim = c(0, max(h$counts)), xlim = range(h$mids)*1.1,
type = 'n', bty = 'n', xlab = 'y', ylab = 'Counts', main = 'Histogram of y')
add your grid
grid()
add your histogram
hist(y, add = TRUE)
Or, as I discovered through this process... you can do it even easier
hist(y)
grid()
hist(y, add = TRUE, col = 'white')
This last method is just redrawing the histogram over the grid.
The base graphics solution suggested by @joran is fine. Alternatives:
d <- data.frame(x=rnorm(1000))
library(lattice)
histogram(~x,data=d,panel=function(...) {
panel.grid(...)
panel.histogram(...) }
)
Or:
library(ggplot2)
qplot(x,data=d,geom="histogram",binwidth=0.1)+theme_bw()+
labs(x="Wind speed", y="Frequency")
(But of course you will have to learn all the details of adjusting labels, titles, etc. ... I'm not actually sure how to do titles in ggplot
...)
Another methods for grid lines in background:
A)
hist( y, panel.first=grid() ) # see: help( plot.default )
box()
B)
plot.new() # new empty plot
nv <- length( pretty(x) ) - 1 # number of vertical grid lines (or set by hand)
nh <- length( pretty(y) ) - 1 # number of horizontal grid lines (or set by hand)
grid( nx = nv, ny = nh ) # preplot grid lines
par( new = TRUE ) # add next plot
plot( x, y ) # plot or hist, etc
box() # if plot hist
Arbitrary lines in background with abline:
C)
How do I draw gridlines using abline() that are behind the data?
D)
# first, be sure there is no +/-Inf, NA, NaN in x and y
# then, make the container plot with two invisible points:
plot( x = range( pretty( x ) ), y = range( pretty( y ) ), type = "n", ann = FALSE )
abline( h = hlines, v = vlines ) # draw lines. hlines, vlines: vectors of coordinates
par( new = TRUE ) # add next plot. It is not necessary with points, lines, segments, ...
plot( x, y ) # plot, hist, etc
box() # if plot hist