Plotting a grid behind data, not in front in R

前端 未结 5 846
一生所求
一生所求 2020-12-30 23:45

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         


        
相关标签:
5条回答
  • 2020-12-31 00:20

    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.

    0 讨论(0)
  • 2020-12-31 00:23

    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)
    

    enter image description here

    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 ....

    0 讨论(0)
  • 2020-12-31 00:28

    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.

    0 讨论(0)
  • 2020-12-31 00:30

    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 ...)

    0 讨论(0)
  • 2020-12-31 00:31

    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
    
    0 讨论(0)
提交回复
热议问题