---
title: "Actogram visualisation"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Actogram visualisation}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse  = TRUE,
  comment   = "#>",
  fig.width = 9,
  fig.height = 12,
  dpi       = 150,
  out.width = "100%"
)
library(zeitR)
if (!requireNamespace("ggplot2", quietly = TRUE)) {
  knitr::opts_chunk$set(eval = FALSE)
  message("ggplot2 is required for this vignette. Install with install.packages(\"ggplot2\").")
} else {
  library(ggplot2)
}
```

An actogram is the standard visualisation for wrist actigraphy data. It lays
out the full epoch-level state sequence as a raster -- one row per calendar
day, time of day on the x-axis -- so that a recording spanning weeks can be
read at a glance. zeitR provides three actogram variants:

| Function | Format | Best for |
|---|---|---|
| `plot_actogram()` | Single column, 24 h | Overview, presentations |
| `plot_actogram_double()` | Double-plotted, 48 h | Phase drift, phase assessment |
| `plot_actogram_activity()` | Double-plotted + activity bars | Intensity + state simultaneously |

All three accept either a `zeitr_result` list from the pipeline or a bare
tibble with `datetime` and `state` columns.

---

## Setup

The examples below use the ActTrust validation recording bundled with zeitR,
run through `run_pipeline_native()`.

```{r run}
FILE <- system.file("extdata", "input1.txt", package = "zeitR")
TZ   <- "America/Sao_Paulo"

result <- run_pipeline_native(FILE, tz = TZ, quiet = TRUE)
```

---

## Single-column actogram

`plot_actogram()` draws one row per calendar day with time of day (00:00 to
24:00) on the x-axis. The oldest day is at the top, following standard
chronobiology convention. Rows are labelled every seven days by default.

```{r single}
plot_actogram(result, tz = TZ)
```

The dark purple band running through the centre of each row is the main sleep
period. The amber gaps are naps; the terracotta blocks are off-wrist episodes.

---

## Double-plotted actogram

`plot_actogram_double()` uses the classic double-plot format from
chronobiology: each recording day appears **twice** -- in the left column of
its own row (x = 00:00 to 24:00) and in the right column of the row above
(x = 24:00 to 48:00). A dashed vertical line marks the 24 h boundary.

When the sleep band drifts diagonally across rows, that drift reflects
day-to-day changes in circadian phase. A stable schedule appears as a
straight vertical band; a free-running rhythm traces a slanted line.

```{r double}
plot_actogram_double(result, tz = TZ)
```

---

## Activity double-plotted actogram

`plot_actogram_activity()` keeps the double-plot layout but replaces filled
tiles with vertical bars. Each bar's height is proportional to the raw ZCMn
activity count; bars are coloured by sleep/wake state. This lets you read
both the intensity of activity and the state classification from a single
plot.

Bar heights are capped at the 99th percentile of non-zero epochs by default
(`activity_cap_quantile = 0.99`), so a handful of outlier bursts do not
compress the rest of the range. Zero-activity epochs (sleep, off-wrist)
receive a thin 2% baseline stub so they remain faintly visible rather than
disappearing entirely.

```{r activity, fig.height = 14}
plot_actogram_activity(result, tz = TZ)
```

---

## Colour customisation

### Inspecting the default palette

`actogram_colours()` returns the named hex vector used as the default palette
across all three functions. Printing it is the quickest way to see the
current defaults before overriding them.

```{r colours, fig.height = 3}
actogram_colours()
```

### Overriding individual colours

Pass a named character vector to the `colours` argument. You only need to
supply the states you want to change; unnamed states keep the default.

```{r custom-colours}
my_cols <- actogram_colours()
my_cols["sleep"]     <- "#1C1A2E"   # darker midnight
my_cols["off-wrist"] <- "#8B4513"   # saddle brown

plot_actogram(result, tz = TZ, colours = my_cols)
```

### Suppressing naps

If your recording has no naps, or you want to simplify the legend, you can
drop the nap level by providing only three colours:

```{r no-nap-cols, eval = FALSE}
plot_actogram(result, tz = TZ,
              colours = c(wake = "#D9C8A0", sleep = "#3B2F6B",
                          "off-wrist" = "#C25E2A"))
```

---

## Date labels and font size

`date_label_every` controls how many rows share a single y-axis tick.
The default is `7` (one tick per week). Reduce it for shorter recordings or
increase it for very long ones.

```{r labels, fig.height = 12}
# Label every 14 days
plot_actogram(result, tz = TZ, date_label_every = 14L)
```

`base_size` sets the base font size passed to `theme_minimal()`:

```{r fontsize, eval = FALSE}
plot_actogram(result, tz = TZ, base_size = 11)   # smaller text
plot_actogram(result, tz = TZ, base_size = 16)   # larger text (presentations)
```

---

## Adding ggplot2 layers

All three functions return a standard `ggplot` object, so you can extend them
with any ggplot2 layer or theme override:

```{r extend}
plot_actogram_double(result, tz = TZ) +
  theme(legend.position = "right")
```

---

## Working with a bare tibble

The functions accept any tibble with `datetime` (POSIXct) and `state`
(integer) columns -- no pipeline required. This is useful if you have
data in a format other than a `zeitr_result`.

```{r bare}
# Subset a few weeks from result$data and plot directly
sub <- result$data[1:5040, ]   # first 3.5 days for illustration
plot_actogram(sub, tz = TZ, title = "First 3.5 days")
```

The `state` column should use zeitR's integer coding:
`0 = wake, 1 = sleep, 4 = off-wrist, 7 = nap`.

---

## Choosing between the three variants

- Use `plot_actogram()` when you want a compact overview -- one row per day,
  simple state raster. Good for reports and presentations.

- Use `plot_actogram_double()` when you want to assess **circadian phase
  drift** across the recording. The 48 h window makes diagonal drift in the
  sleep band visible at a glance.

- Use `plot_actogram_activity()` when activity intensity matters -- for
  example, when comparing sedentary and active participants, or checking
  whether an unexpectedly short TST reflects genuine low activity or a
  classification artefact.

---

## Next steps

- `vignette("sleep-analysis")` -- CSPD pipeline walkthrough
- `vignette("vallim-pipeline")` -- Vallim classification rule set
- `?compute_sleep_metrics`, `?compute_cpd_metrics` -- day-type sleep summary
  and chronotype metrics
- `?export_hypnogram` -- export epoch-level staging to hypnoR
- `?label_states` -- convert integer state codes to a human-readable factor
