plotting

lifelines.plotting.add_at_risk_counts(*fitters, labels: Iterable | bool | None = None, rows_to_show=None, ypos=-0.6, xticks=None, ax=None, at_risk_count_from_start_of_period=False, **kwargs)

Add counts showing how many individuals were at risk, censored, and observed, at each time point in survival/hazard plots.

Tip: you probably want to call plt.tight_layout() afterwards.

Parameters:
  • fitters – One or several fitters, for example KaplanMeierFitter, WeibullFitter, NelsonAalenFitter, etc…

  • labels – provide labels for the fitters, default is to use the provided fitter label. Set to False for no labels.

  • rows_to_show (list) – a sub-list of [‘At risk’, ‘Censored’, ‘Events’]. Default to show all.

  • ypos – make more positive to move the table up.

  • xticks (list) – specify the time periods (as a list) you want to evaluate the counts at.

  • at_risk_count_from_start_of_period (bool, default False.) – By default, we use the at-risk count from the end of the period. This is what other packages, and KMunicate suggests, but the same issue keeps coming up with users. #1383, #1316 and discussion #1229. This makes the adjustment.

  • ax – a matplotlib axes

Returns:

The axes which was used.

Return type:

ax

Examples

# First train some fitters and plot them
fig = plt.figure()
ax = plt.subplot(111)

f1 = KaplanMeierFitter()
f1.fit(data)
f1.plot(ax=ax)

f2 = KaplanMeierFitter()
f2.fit(data)
f2.plot(ax=ax)

# These calls below are equivalent
add_at_risk_counts(f1, f2)
add_at_risk_counts(f1, f2, ax=ax, fig=fig)
plt.tight_layout()

# This overrides the labels
add_at_risk_counts(f1, f2, labels=['fitter one', 'fitter two'])
plt.tight_layout()

# This hides the labels
add_at_risk_counts(f1, f2, labels=False)
plt.tight_layout()

# Only show at-risk:
add_at_risk_counts(f1, f2, rows_to_show=['At risk'])
plt.tight_layout()

References

Morris TP, Jarvis CI, Cragg W, et al. Proposals on Kaplan–Meier plots in medical research and a survey of stakeholder views: KMunicate. BMJ Open 2019;9:e030215. doi:10.1136/bmjopen-2019-030215

lifelines.plotting.cdf_plot(model, timeline=None, ax=None, **plot_kwargs)

This plot compares the empirical CDF (derived by KaplanMeier) vs the model CDF.

Parameters:
  • model (lifelines univariate model)

  • timeline (iterable)

  • ax (matplotlib axis)

lifelines.plotting.loglogs_plot(cls, loc=None, iloc=None, show_censors=False, censor_styles=None, ax=None, **kwargs)

Specifies a plot of the log(-log(SV)) versus log(time) where SV is the estimated survival function.

lifelines.plotting.plot_interval_censored_lifetimes(lower_bound, upper_bound, entry=None, left_truncated=False, sort_by_lower_bound=True, event_observed_color='#A60628', event_right_censored_color='#348ABD', ax=None, **kwargs)

Returns a lifetime plot for interval censored data.

Parameters:
  • lower_bound ((n,) numpy array or pd.Series) – the start of the period the subject experienced the event in.

  • upper_bound ((n,) numpy array or pd.Series) – the end of the period the subject experienced the event in. If the value is equal to the corresponding value in lower_bound, then the individual’s event was observed (not censored).

  • entry ((n,) numpy array or pd.Series) – offsetting the births away from t=0. This could be from left-truncation, or delayed entry into study.

  • left_truncated (boolean) – if entry is provided, and the data is left-truncated, this will display additional information in the plot to reflect this.

  • sort_by_lower_bound (boolean) – sort by the lower_bound vector

  • event_observed_color (str) – default: “#A60628”

  • event_right_censored_color (str) – default: “#348ABD” applies to any individual with an upper bound of infinity.

Return type:

ax

Examples

import pandas as pd
import numpy as np
from lifelines.plotting import plot_interval_censored_lifetimes
df = pd.DataFrame({'lb':[20,15,30, 10, 20, 30], 'ub':[25, 15, np.infty, 20, 20, np.infty]})
ax = plot_interval_censored_lifetimes(lower_bound=df['lb'], upper_bound=df['ub'])
lifelines.plotting.plot_lifetimes(durations, event_observed=None, entry=None, left_truncated=False, sort_by_duration=True, event_observed_color='#A60628', event_censored_color='#348ABD', ax=None, **kwargs)

Returns a lifetime plot, see examples: https://lifelines.readthedocs.io/en/latest/Survival%20Analysis%20intro.html#Censoring

Parameters:
  • durations ((n,) numpy array or pd.Series) – duration (relative to subject’s birth) the subject was alive for.

  • event_observed ((n,) numpy array or pd.Series) – array of booleans: True if event observed, else False.

  • entry ((n,) numpy array or pd.Series) – offsetting the births away from t=0. This could be from left-truncation, or delayed entry into study.

  • left_truncated (boolean) – if entry is provided, and the data is left-truncated, this will display additional information in the plot to reflect this.

  • sort_by_duration (boolean) – sort by the duration vector

  • event_observed_color (str) – default: “#A60628”

  • event_censored_color (str) – default: “#348ABD”

Return type:

ax

Examples

from lifelines.datasets import load_waltons
from lifelines.plotting import plot_lifetimes
T, E = load_waltons()["T"], load_waltons()["E"]
ax = plot_lifetimes(T.loc[:50], event_observed=E.loc[:50])
lifelines.plotting.qq_plot(model, ax=None, scatter_color='k', **plot_kwargs)

Produces a quantile-quantile plot of the empirical CDF against the fitted parametric CDF. Large deviances away from the line y=x can invalidate a model (though we expect some natural deviance in the tails).

Parameters:
  • model (obj) – A fitted lifelines univariate parametric model, like WeibullFitter

  • plot_kwargs – kwargs for the plot.

Returns:

The axes which was used.

Return type:

ax

Examples

from lifelines import *
from lifelines.plotting import qq_plot
from lifelines.datasets import load_rossi
df = load_rossi()
wf = WeibullFitter().fit(df['week'], df['arrest'])
qq_plot(wf)

Notes

The interval censoring case uses the mean between the upper and lower bounds.

lifelines.plotting.rmst_plot(model, model2=None, t=inf, ax=None, text_position=None, **plot_kwargs)

This functions plots the survival function of the model plus it’s area-under-the-curve (AUC) up until the point t. The AUC is known as the restricted mean survival time (RMST).

To compare the difference between two models’ survival curves, you can supply an additional model in model2.

Parameters:
  • model (lifelines.UnivariateFitter)

  • model2 (lifelines.UnivariateFitter, optional) – used to compute the delta RMST of two models

  • t (float) – the upper bound of the expectation

  • ax (axis)

  • text_position (tuple) – move the text position of the RMST.

Examples

from lifelines.utils import restricted_mean_survival_time
from lifelines.datasets import load_waltons
from lifelines.plotting import rmst_plot

df = load_waltons()
ix = df['group'] == 'miR-137'
T, E = df['T'], df['E']
time_limit = 50

kmf_exp = KaplanMeierFitter().fit(T[ix], E[ix], label='exp')
kmf_con = KaplanMeierFitter().fit(T[~ix], E[~ix], label='control')

ax = plt.subplot(311)
rmst_plot(kmf_exp, t=time_limit, ax=ax)

ax = plt.subplot(312)
rmst_plot(kmf_con, t=time_limit, ax=ax)

ax = plt.subplot(313)
rmst_plot(kmf_exp, model2=kmf_con, t=time_limit, ax=ax)