Search code examples
rplotaxis-labels

Define sequence of axis labels


I want to label certain tick marks with a regular sequence, and leave marks in between without labels.

My data ("coefs_PA") is like this

structure(list(year = c(1998, 1999, 2000, 2001, 2002, 2003, 
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 
2015, 2016, 2017, 2018, 2019), estimate = c(0.111, 0.081, -0.106, 
2.571, 0.606, -0.234, 0.325, 0.891, 0.062, 0.37, -0.041, 0.09, 
0.436, 0.08, -0.973, 0.147, -0.116, 0.602, 0.385, 0.274, 0.118, 
0.682), sd = c(0, 0.488, 0.411, 1.282, 0.473, 0.447, 0.427, 0.52, 
0.477, 0.394, 0.384, 0.379, 0.404, 0.416, 0.43, 0.419, 0.464, 
0.788, 0.456, 0.451, 0.427, 0.467)), row.names = c(NA, -22L), class = "data.frame")

and with the following code

library(Hmisc)

plot(coefs_PA$year, coefs_PA$estimate, xaxt='n', yaxt="n", xlab=NA, ylab=NA, pch=17,
     ylim = c(min(coefs_PA$estimate - coefs_PA$sd),
              max((coefs_PA$estimate + coefs_PA$sd))))

with(data = coefs_PA, expr = errbar(year, estimate, estimate+sd,
                                    estimate-sd, add = TRUE, cap = 0))

axis(2, las=2, at = c(-1:4, 1))
minor.tick(nx = 0, ny = 2, tick.ratio = 0.7)
axis(1, at=coefs_PA$fecha)
title(ylab=expression("Logit (P"[p]*")"), line=1.6, cex.lab=1)
mtext(side=3, line=0.2, "Year", font=2, cex=1.0)

I get the following figure

enter image description here

I want the values of the x-axis to be 2000, 2005, 2010, 2015 and the remaining tick marks to be blank. I have tried to get it with this

axis(1, at = coefs_fechas_PA$fecha,
     labels = c(rep("",2), "2000", rep("",4), "2005", rep("",4), 
                "2010", rep("",4), "2015", rep("",4))))

but it didn´t work.

Any hint will be more than welcome.


Solution

  • Set

    years <- do.call(seq, as.list(range(coefs_PA$year)))
    years5 <- seq(2000, 2020, by = 5)
    # or, more dynamically
    years5 <- years[ years %% 5 == 0 ]
    
    plot(coefs_PA$year, coefs_PA$estimate, xaxt='n', yaxt="n", xlab=NA, ylab=NA, pch=17,
         ylim=c(min(coefs_PA$estimate - coefs_PA$sd), max((coefs_PA$estimate + coefs_PA$sd))))
    
    axis(1, years, labels = ifelse(years %in% years5, years, years[NA]))
    

    plot with axis labels/ticks

    (And then all of your other plot components ... omitted for brevity.)

    Note: If we instead do ifelse(.., years, ""), then the desired years may not show because the empty strings are still causing potential overlap and/or problems with the labels. We can use ifelse(.., years, NA), and that's perhaps more intuitive, but programmatically speaking I chose years[NA] for a couple of reasons:

    • ifelse-replacements (dplyr::if_else and data.table::fifelse come to mind) generally complain when the class of objects in the yes= and no= arguments are different. Did you know that there are at least six types of NA, all different classes?
    • I could have hard-coded NA_integer_ since years is an integer vector, but I didn't want to assume that ... perhaps you'll have numeric instead (and therefore should be using NA_real_). It's perhaps a little more declarative that I want the same NA as the class of years, so years[NA] gives me that. (Perhaps my programming OCD is showing.)