---
title: "Plotting lag-sequential models"
author:
  - "Mohammed Saqr"
  - "Sonsoles López-Pernas"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Plotting lag-sequential models}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>", message = FALSE,
                      warning = FALSE, dpi = 130, fig.width = 6.8,
                      fig.height = 5.4, out.width = "100%",
                      fig.align = "center")
set.seed(2026)
library(lagdynamics)
old_options <- options(digits = 3)
has_cograph <- requireNamespace("cograph", quietly = TRUE)
has_ggplot2 <- requireNamespace("ggplot2", quietly = TRUE)
fit <- lsa(engagement)
```

`lagdynamics` has one plotting verb, `plot(fit, type = )`, plus dedicated
plots for the resampling and comparison results. Every view of a fit
displays the same quantity -- the adjusted residual, the departure of a
transition from chance -- and differs only in geometry. The single fit
used throughout is the bundled `engagement` data (138 students, three
engagement states).

| view | call | backend |
|---|---|---|
| residual heatmap | `plot(fit)` | ggplot2 |
| residual network | `plot(fit, type = "network")` | cograph |
| transition (TNA) network | `plot(fit, type = "network", weights = "tna")` | cograph |
| chord diagram | `plot(fit, type = "chord")` | cograph |
| polar sunburst | `plot(fit, type = "sunburst")` | ggplot2 |
| uncertainty forest | `plot(bootstrap_lsa(fit))`, `plot(certainty_lsa(fit))` | ggplot2 |
| group barrel | `plot(compare_lsa(g))`, `plot(bayes_compare_lsa(g))` | ggplot2 |

**Colour.** Two conventions are used, by purpose. The residual *heatmap*,
*chord*, and *sunburst* use the residual diverging scale (warm = over-
represented, cool = avoided). The *network* and *group comparison* plots
follow the wider Transition Network Analysis (TNA) convention -- **blue =
more than chance**, **red = less** (avoided edges dashed) -- so an `lsa`
network reads like any other transition network.

# Residual heatmap

The default. Rows are the current state, columns the next; colour is the
adjusted residual. `which` selects the matrix.

```{r heatmap, eval = has_ggplot2}
plot(fit)                       # adjusted residuals (default)
plot(fit, which = "prob")       # transition probabilities
```

# Residual network

The same residuals as a directed graph: **blue** edges (solid) are
over-represented, **red** edges (dashed, with a soft halo) are avoided.

```{r net-residual, eval = has_cograph}
plot(fit, type = "network")
```

# Transition network (a TNA model)

Weight the edges by probability and the view becomes the familiar
transition network, drawn in the Transition Network Analysis (TNA) style by
`cograph::splot()`: coloured nodes, a per-node initial-probability ring, and
weighted directed edges. This shows what happens, where the residual network
shows what is surprising.

```{r net-transition, eval = has_cograph}
plot(fit, type = "network", weights = "tna")
```

# Chord and sunburst

A chord diagram of the transition flow, and a polar sunburst of each
state's outgoing distribution.

```{r chord, eval = has_cograph}
plot(fit, type = "chord")
```

```{r sunburst, eval = has_ggplot2}
plot(fit, type = "sunburst")                 # rose (default)
plot(fit, type = "sunburst", style = "wedge")  # frequency wedges
```

# Uncertainty forests

A fitted edge is one estimate; the forest shows its interval. Both the
resampling bootstrap and the analytic certainty plot as a circular forest
of per-edge intervals.

```{r forest, eval = has_ggplot2, fig.height = 6.5}
plot(bootstrap_lsa(fit, R = 200))            # resampling CIs
plot(certainty_lsa(fit))                     # analytic credible intervals
```

# Group comparison

For a real grouping we use the bundled long event log
`group_regulation_long`, and fit one model per achievement group.

```{r gfit}
gfit <- lsa(group_regulation_long, actor = "Actor",
            action = "Action", time = "Time", group = "Achiever")
```

`plot()` on a comparison draws a back-to-back **barrel**: each group's bar
runs to one side, the higher group's bar is bordered (darker for a larger
difference), and the centre chip carries the difference p-value.

```{r barrel, eval = has_ggplot2, fig.height = 7}
cmp <- compare_lsa(gfit, R = 500)
plot(cmp)                                    # frequency-ranked rows
plot(cmp, rank = "effect")                   # surface avoided (red) edges
plot(cmp, style = "heatmap")                 # full-grid difference
```

The Bayesian comparison reuses the same barrel, with the credible
posterior in place of the permutation p-value.

```{r bayes-barrel, eval = has_ggplot2, fig.height = 7}
plot(bayes_compare_lsa(gfit, seed = 1))
```

# Grouped fits

Every `type` works on a grouped fit, drawing one panel per group
(`combined = FALSE`, the default) or a single tiled figure
(`combined = TRUE`).

```{r grouped, eval = has_ggplot2}
plot(gfit)                                   # one heatmap per group
```

# The worker functions

`plot(fit, type = )` is a front door over exported workers, each with its
own full argument list:

```{r workers, eval = FALSE}
plot_transitions(fit, weights = "residuals", significant = TRUE)  # network
plot_chords(fit, width = "prob")                                  # chord
plot_polar(fit, style = "wedge")                                  # sunburst
plot_forest(bootstrap_lsa(fit), n_top = 12)                       # forest
```

# In short

```r
plot(fit)                                   # residual heatmap (default)
plot(fit, type = "network")                 # residual network (blue = more)
plot(fit, type = "network", weights = "tna")   # transition network (a TNA model)
plot(fit, type = "chord"); plot(fit, type = "sunburst")
plot(bootstrap_lsa(fit)); plot(certainty_lsa(fit))   # uncertainty forests
plot(compare_lsa(gfit)); plot(bayes_compare_lsa(gfit))  # group barrels
plot(gfit)                                  # grouped: one panel per group
```

```{r cleanup, include = FALSE}
options(old_options)
```
