23

With acf we can make ACF plot in base R graph.

x <- lh
acf(x)

enter image description here

The following code can be used to get the ACF plot in ggplot2.

conf.level <- 0.95
ciline <- qnorm((1 - conf.level)/2)/sqrt(length(x))
bacf <- acf(x, plot = FALSE)
bacfdf <- with(bacf, data.frame(lag, acf))

library(ggplot2)
q <- ggplot(data=bacfdf, mapping=aes(x=lag, y=acf)) +
       geom_bar(stat = "identity", position = "identity")
q

enter image description here

Question

How to get lines rather than bars or how to set the width of bars so that they look like lines? Thanks

MYaseen208
  • 22,666
  • 37
  • 165
  • 309
  • 2
    Note that there's a `ggplot2` wrapper for this: https://github.com/dewittpe/qwraps. Install with `devtools::install_github("dewittpe/qwraps")`. – krlmlr Sep 26 '14 at 07:47
  • This is extremely useful post. I'm wondering if creating Stata-like *[Cross-correlogram for bivariate time series](http://www.stata.com/support/faqs/graphics/gph/graphdocs/cross-correlogram-for-bivariate-time-series/)* would be achievable with use of the suggested approach? – Konrad Jan 17 '16 at 23:36
  • 2
    @konrad try the following code: `library(ggfortify) p1 <- autoplot(acf(AirPassengers, plot = FALSE), conf.int.fill = '#0000FF', conf.int.value = 0.8, conf.int.type = 'ma') print(p1) library(cowplot) ggdraw(switch_axis_position(p1, axis = 'xy', keep = 'xy'))` – MYaseen208 Jan 18 '16 at 15:29

6 Answers6

26

You're probably better off plotting with line segments via geom_segment()

library(ggplot2)

set.seed(123)
x <- arima.sim(n = 200, model = list(ar = 0.6))

bacf <- acf(x, plot = FALSE)
bacfdf <- with(bacf, data.frame(lag, acf))

q <- ggplot(data = bacfdf, mapping = aes(x = lag, y = acf)) +
       geom_hline(aes(yintercept = 0)) +
       geom_segment(mapping = aes(xend = lag, yend = 0))
q

enter image description here

Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
  • 4
    This answer is super old (and still useful). Just to notice that you forgot to add `geom_hline(aes(yintercept = ciline), linetype = 3, color = 'darkblue') + geom_hline(aes(yintercept = -ciline), linetype = 3, color = 'darkblue')` to mimic the lines in the original base plot – Romain Dec 15 '17 at 18:34
  • Dashed line: linetype=2 – Rottmann Jan 28 '18 at 19:37
5

How about using geom_errorbar with width=0?

ggplot(data=bacfdf, aes(x=lag, y=acf)) + 
    geom_errorbar(aes(x=lag, ymax=acf, ymin=0), width=0)
shadow
  • 21,823
  • 4
  • 63
  • 77
4

@konrad; try the following code:

library(ggfortify)
p1 <- autoplot(acf(AirPassengers, plot = FALSE), conf.int.fill = '#0000FF', conf.int.value = 0.8, conf.int.type = 'ma') 
print(p1) 
library(cowplot) 
ggdraw(switch_axis_position(p1, axis = 'xy', keep = 'xy'))

enter image description here

MYaseen208
  • 22,666
  • 37
  • 165
  • 309
2

From the forecast package comes a function ggtsdisplay that plots both ACF and PACF with ggplot. x is the residuals from the model fit (fit$residuals).

forecast::ggtsdisplay(x,lag.max=30)
Gucci148
  • 1,977
  • 1
  • 13
  • 4
2

From your answers, I synthesized a ggplot ACF / PACF plotting method :

    require(zoo)
    require(tseries)
    require(ggplot2)
    require(cowplot)

    ts= zoo(data[[2]]) # data[[2]] because my time series data was the second column

    # Plot ACP / ACF with IC
    # How to compute IC for ACF and PACF :
    # https://stats.stackexchange.com/questions/211628/how-is-the-confidence-interval-calculated-for-the-acf-function
    ic_alpha= function(alpha, acf_res){
      return(qnorm((1 + (1 - alpha))/2)/sqrt(acf_res$n.used))
    }

    ggplot_acf_pacf= function(res_, lag, label, alpha= 0.05){
      df_= with(res_, data.frame(lag, acf))
      
      # IC alpha
      lim1= ic_alpha(alpha, res_)
      lim0= -lim1
      
      
      ggplot(data = df_, mapping = aes(x = lag, y = acf)) +
        geom_hline(aes(yintercept = 0)) +
        geom_segment(mapping = aes(xend = lag, yend = 0)) +
        labs(y= label) +
        geom_hline(aes(yintercept = lim1), linetype = 2, color = 'blue') +
        geom_hline(aes(yintercept = lim0), linetype = 2, color = 'blue')
    }

    acf_ts= ggplot_acf_pacf(res_= acf(ts, plot= F)
                   , 20
                   , label= "ACF")
    pacf_ts= ggplot_acf_pacf(res_= pacf(ts, plot= F)
                         , 20
                         , label= "PACF")
    # Concat our plots
    acf_pacf= plot_grid(acf_ts, pacf_ts, ncol = 2, nrow = 1)
    acf_pacf

Results:

enter image description here

Sinval
  • 1,315
  • 1
  • 16
  • 25
2

forecast::ggAcf() is another option:

library(ggplot2)
library(forecast)

ggAcf(wineind,lag.max=24)+
  labs(title='wineind')
kakarot
  • 376
  • 4
  • 13