## viz.plot_cif()


Plot cumulative incidence functions from a fitted Aalen-Johansen estimator.


Usage

``` python
viz.plot_cif(
    aj,
    *,
    conf_int=True,
    risk_table=False,
    times=None,
    title=None,
    xlab="Time",
    ylab="Cumulative incidence",
    width=400,
    height=300,
    backend="altair"
)
```


Renders one cumulative incidence curve per competing cause as a right-continuous step function. The chart is faceted by cause (one panel per event type). Stratified fits (produced by passing `by=` to [AalenJohansen.fit()](AalenJohansen.md#greenwood.AalenJohansen.fit)) draw one colored line per group within each panel. An optional shaded confidence band shows the point-wise uncertainty.


## Parameters


`aj: AalenJohansen`  
A fitted [AalenJohansen](AalenJohansen.md#greenwood.AalenJohansen) object. Unstratified fits draw a single curve per panel. Stratified fits draw one colored curve per group.

`conf_int: bool = ``True`  
If `True` (default), draw a shaded point-wise confidence band around each curve.

`risk_table: bool = ``False`  
If `True`, stack an aligned numbers-at-risk table beneath the curves.

`times: Any = None`  
Query times for the numbers-at-risk table (used only when `risk_table=True`). Defaults to six evenly spaced times from `0` to the largest observed follow-up time.

`title: str | None = None`  
Optional overall plot title.

`xlab: str = ``"Time"`  
X-axis label (default `"Time"`).

`ylab: str = ``"Cumulative incidence"`  
Y-axis label (default `"Cumulative incidence"`).

`width: int = ``400`  
Width of each cause panel in pixels (default `400`).

`height: int = ``300`  
Height of each cause panel in pixels (default `300`).

`backend: str = ``"altair"`  
Plotting backend. Currently only `"altair"` is supported.


## Returns


`altair.Chart`  
An interactive Altair chart. Each panel corresponds to one competing cause. Groups are distinguished by color.


## Examples

Fit the Aalen-Johansen estimator on the bundled mgus2 dataset, where patients may progress to malignancy (PCM) or die first:


``` python
import numpy as np
import greenwood as gw

# Load data and build a competing-risks response
mg = gw.load_dataset("mgus2", backend="polars")
etime = np.where(mg["pstat"] == 1, mg["ptime"], mg["futime"])
cause = np.where(mg["pstat"] == 1, 1, 2 * mg["death"])
y = gw.Surv.multistate(etime, event=cause, states=("pcm", "death"))

# Fit the Aalen-Johansen estimator and plot cumulative incidence
aj = gw.AalenJohansen().fit(y)
gw.plot_cif(aj)
```


<style>
  #altair-viz-30fed25195644fd2a82d4cf97a191803.vega-embed {
    width: 100%;
    display: flex;
  }

  #altair-viz-30fed25195644fd2a82d4cf97a191803.vega-embed details,
  #altair-viz-30fed25195644fd2a82d4cf97a191803.vega-embed details summary {
    position: relative;
  }
</style>


Pass `by=` to stratify by a covariate and compare groups across causes:


``` python
# Stratify by sex and compare groups across causes
aj_sex = gw.AalenJohansen().fit(y, by=mg["sex"])
gw.plot_cif(aj_sex, title="Cumulative incidence by sex")
```


<style>
  #altair-viz-275fa284c9b44f5990db5e2bf2131c2e.vega-embed {
    width: 100%;
    display: flex;
  }

  #altair-viz-275fa284c9b44f5990db5e2bf2131c2e.vega-embed details,
  #altair-viz-275fa284c9b44f5990db5e2bf2131c2e.vega-embed details summary {
    position: relative;
  }
</style>


Add an aligned numbers-at-risk table beneath the curves:


``` python
# Add a numbers-at-risk table beneath the curves
gw.plot_cif(aj_sex, risk_table=True)
```


<style>
  #altair-viz-206f913ef08d4e3fb18bcdcf844c5e28.vega-embed {
    width: 100%;
    display: flex;
  }

  #altair-viz-206f913ef08d4e3fb18bcdcf844c5e28.vega-embed details,
  #altair-viz-206f913ef08d4e3fb18bcdcf844c5e28.vega-embed details summary {
    position: relative;
  }
</style>
