Search code examples
rplot

R is ignoring xaxp while plotting data.table


x = c(1, 2, 2, 3, 3, 3, 4, 4, 5)
x.tab = table(x)
plot(x.tab, xlim = c(0, 10), xaxp=c(0, 10, 10))

(Unfortunately, I do not have enough reputation to post image, but received graph has only tick marks 1 to 5, instead of intended 0 to 10)

Why does R just ignore xaxp? I understand that I could factor x to levels 0:10 (i.e. add x = factor(x, levels=0:10)) and that would be solution, but why doesn't parameter xaxp work as intended? And by the way how to extract frequencies as vector from x.tab without complicated magic?


Solution

  • You can see the source to the plot.table method by running graphics:::plot.table. It contains this near the end:

            plot(x0, unclass(x), type = type, ylim = ylim, xlab = xlab, 
                ylab = ylab, frame.plot = frame.plot, lwd = lwd, 
                ..., xaxt = "n")
            localaxis <- function(..., col, bg, pch, cex, lty, log) axis(...)
            if (!isFALSE(list(...)$axes)) 
                localaxis(1, at = x0, labels = nx, ...)
    

    So you can see that the call to the default plot method specifies no axis via xaxt = "n", and then it draws an axis with ticks at x0 values, which in this case are the values 1:5.

    That's not what you wanted, so what you can do is ask it not to plot axes, then draw them manually yourself, e.g.

    x = c(1, 2, 2, 3, 3, 3, 4, 4, 5)
    x.tab = table(x)
    plot(x.tab, xlim = c(0, 10), axes = FALSE)
    axis(1, xaxp=c(0, 10, 10))
    axis(2)
    

    Created on 2024-03-30 with reprex v2.1.0

    Another way to do this is to make x into a factor with levels 0 to 10, e.g. x <- factor(x, levels = 0:10). Then plot.table will do almost what you want without any optional arguments. (It will include dots for the zero counts, which the code above doesn't do.)