Plots
compute_diagnostics
- openpkpd.plots.diagnostics.compute_diagnostics(population_model, result)[source]
Compute diagnostic DataFrame from a fitted model.
- Parameters:
population_model (
PopulationModel) – Assembled PopulationModel with dataset.result (
EstimationResult) – EstimationResult from model.fit().
- Return type:
- Returns:
DataFrame with ID, TIME, DV, PRED, IPRED, RES, IRES, WRES, IWRES, CWRES, ETA1..ETAn, MDV, EVID, and any covariate columns. Only rows with EVID=0 and MDV=0 are included.
GOF plots
- openpkpd.plots.gof.diagnostic_panel(diag_df, *, figsize=(18, 9), title='Diagnostic Panel')[source]
2×4 combined panel of all 7 GOF plots (includes CWRES histogram).
- openpkpd.plots.gof.dv_vs_ipred(diag_df, *, log_scale=False, ax=None, title='DV vs IPRED')[source]
Scatter plot of DV vs IPRED with identity line.
- openpkpd.plots.gof.dv_vs_pred(diag_df, *, log_scale=False, ax=None, title='DV vs PRED')[source]
Scatter plot of DV vs PRED with identity line.
- openpkpd.plots.gof.cwres_vs_time(diag_df, *, ax=None, title='CWRES vs TIME')[source]
CWRES scatter vs TIME with zero line and ±2 bands.
- openpkpd.plots.gof.cwres_vs_pred(diag_df, *, ax=None, title='CWRES vs PRED')[source]
CWRES scatter vs PRED with zero line and ±2 bands.
- openpkpd.plots.gof.cwres_qq(diag_df, *, ax=None, title='CWRES Q-Q Plot')[source]
Q-Q normal probability plot of CWRES.
- openpkpd.plots.gof.abs_iwres_vs_ipred(diag_df, *, ax=None, title='|IWRES| vs IPRED')[source]
Absolute IWRES scatter versus IPRED.
openpkpd.plots.gof_panel is a convenience alias for
diagnostic_panel(), the seven-panel goodness-of-fit
figure.
PK plots
- openpkpd.plots.pk.spaghetti_plot(diag_df, *, log_y=False, mean_overlay=True, alpha=0.35, ax=None, title='Spaghetti Plot')[source]
Overlaid individual IPRED profiles.
- openpkpd.plots.pk.concentration_time(diag_df, *, log_y=False, individual=True, mean_overlay=True, highlight_ids=None, ax=None, title='Concentration-Time Profile')[source]
Individual and/or mean concentration-time plot.
- Parameters:
diag_df (
DataFrame) – Diagnostic DataFrame from compute_diagnostics().log_y (
bool) – Use log scale on y-axis.individual (
bool) – Plot individual IPRED lines.mean_overlay (
bool) – Overlay the mean IPRED profile.highlight_ids (
list[int] |None) – Subject IDs to highlight with distinct color.ax – Existing axes to plot into.
title (
str) – Plot title.
PD plots
- openpkpd.plots.pd.effect_time(diag_df, effect_col, *, individual=True, mean_overlay=True, ax=None, title='Effect-Time Profile')[source]
Effect vs time plot.
- openpkpd.plots.pd.emax_curve(diag_df, conc_col, effect_col, *, emax=None, ec50=None, gamma=1.0, e0=0.0, ax=None, title='Emax Curve')[source]
Observed E vs C scatter with optional Emax model overlay.
- Parameters:
diag_df (
DataFrame) – Diagnostic DataFrame.conc_col (
str) – Column for concentration.effect_col (
str) – Column for effect.emax (
float|None) – Emax parameter (skip overlay if None).ec50 (
float|None) – EC50 parameter (skip overlay if None).gamma (
float) – Hill exponent (default 1.0).e0 (
float) – Baseline effect.ax – Existing axes.
title (
str) – Plot title.
- openpkpd.plots.pd.hysteresis_loop(diag_df, conc_col, effect_col, *, color_by_time=True, ax=None, title='Hysteresis Loop')[source]
C–E loop colored by time (one loop per subject, then mean).
ETA plots
- openpkpd.plots.eta.eta_histograms(diag_df, omega, *, n_cols=3, bins=20, overlay_normal=True, title='ETA Distributions')[source]
Histogram of each ETA with optional N(0, omega_kk) overlay.
- Parameters:
- openpkpd.plots.eta.eta_pairs(diag_df, *, alpha=0.6, title='ETA Pairs')[source]
Pairs scatter matrix of all ETA columns.
Model performance
- openpkpd.plots.model_perf.ofv_history(result, *, log_scale=False, ax=None, title='OFV History')[source]
Line plot of OFV across outer iterations.
- Parameters:
result (
EstimationResult) – EstimationResult with ofv_history list.log_scale (
bool) – Use log scale on y-axis.ax – Existing axes.
title (
str) – Plot title.
- openpkpd.plots.model_perf.vpc(diag_df, population_model=None, result=None, *, vpc_result=None, n_sim=200, percentiles=(5.0, 50.0, 95.0), stratify_col=None, ax=None, title='Visual Predictive Check')[source]
VPC: overlay observed vs simulated percentile bands.
Simulated percentile bands are shown as shaded areas; observed percentiles are plotted as lines over observed data scatter.
Can be called in two ways:
- With a VPCResult object (from VPCEngine.compute()):
vpc(diag_df, vpc_result=my_vpc_result)
- With raw PopulationModel + EstimationResult (runs simulation internally):
vpc(diag_df, population_model, result, n_sim=200)
- Parameters:
diag_df (
DataFrame) – Diagnostic DataFrame (from compute_diagnostics()).population_model (
PopulationModel|None) – Assembled PopulationModel (required if vpc_result is None).result (
EstimationResult|None) – EstimationResult (required if vpc_result is None).vpc_result (
Any|None) – Pre-computed VPCResult from VPCEngine (optional). If provided, population_model and result are ignored.n_sim (
int) – Number of Monte Carlo simulations (used when vpc_result is None). Must be > 0.percentiles (
tuple[float,float,float]) – Three percentile values (low, mid, high) as (5, 50, 95).stratify_col (
str|None) – Column to stratify on (single plot if None).ax – Existing matplotlib Axes to draw on.
title (
str) – Plot title.
- Returns:
matplotlib.figure.Figure.
- Raises:
ValueError – If n_sim <= 0 or if neither vpc_result nor population_model is provided.
Simulation-based plots
- openpkpd.plots.simulation.vpc_plot(vpc_result, title='Visual Predictive Check', obs_color='#333333', sim_pi_color='#3498DB', sim_median_color='#E74C3C', figsize=(10, 6), log_y=False, ax=None)[source]
VPC plot: observed data overlaid with simulated prediction intervals.
- Produces a standard VPC figure with:
Grey dots: individual observed DV values
Blue shaded regions: 90% PI bands for simulated 5th and 95th percentiles
Red shaded region: 90% PI band for simulated median (50th percentile)
Solid colored lines: medians of simulated percentile bands
Dashed black lines: observed 5th, 50th, 95th percentiles (binned by time)
Accepts either a VPCResult object (from openpkpd.simulation.vpc.VPCEngine) or any object with observed_df, simulated_df, obs_percentiles, and sim_percentiles attributes.
- Parameters:
vpc_result (
Any) – VPCResult from VPCEngine.compute(), or object with observed_df, obs_percentiles, sim_percentiles attributes.title (
str) – Plot title string.obs_color (
str) – Color for observed data points and observed percentile lines.sim_pi_color (
str) – Color for simulated PI shaded regions.sim_median_color (
str) – Color for simulated median shaded region.figsize (
tuple[float,float]) – Figure size (width, height) in inches.log_y (
bool) – If True, use log scale on the y-axis.ax (
Any|None) – Existing matplotlib Axes to draw on (creates new figure if None).
- Return type:
- Returns:
matplotlib.figure.Figure object.
- Raises:
ImportError – If matplotlib is not installed.
- openpkpd.plots.simulation.pcvpc_plot(diag_df, vpc_result, *, percentiles=(5.0, 50.0, 95.0), log_y=False, figsize=(10, 6), title='Prediction-Corrected VPC')[source]
Prediction-corrected VPC (pcVPC).
Observed and simulated concentrations are normalized by the population prediction (PRED) at each time point, removing the influence of dose and design heterogeneity.
Correction: DV_pc = DV * median(PRED_sim_bin) / PRED_obs
- Parameters:
- Return type:
- Returns:
matplotlib.figure.Figure.
- openpkpd.plots.simulation.stratified_vpc_plot(diag_df, vpc_result, stratify_col, *, percentiles=(5.0, 50.0, 95.0), log_y=False, n_cols=2, title='Stratified VPC')[source]
Multi-panel VPC stratified by a covariate column.
One VPC panel is drawn per unique value of
stratify_col. Each panel uses the samevpc_plotstyle (observed scatter + simulated PI bands). Subsets ofdiag_dfare used for the observed data in each panel; the simulated percentiles fromvpc_resultare applied to the matching stratum rows.- Parameters:
diag_df (
Any) – Diagnostic DataFrame withstratify_colpresent.vpc_result (
Any) – VPCResult fromVPCEngine.stratify_col (
str) – Column name to stratify on.percentiles (
tuple[float,float,float]) – Percentile triplet.log_y (
bool) – Log scale on y-axis.n_cols (
int) – Number of columns.title (
str) – Overall figure title.
- Return type:
- Returns:
matplotlib.figure.Figure.
- openpkpd.plots.simulation.npde_plot(diagnostic_df, title='NPDE Diagnostics', figsize=(12, 8))[source]
Four-panel NPDE diagnostic plot.
- Produces a 2x2 figure panel showing:
NPDE vs TIME — scatter with zero line and +/-1.96 bands
NPDE vs PRED — scatter with zero line and +/-1.96 bands
NPDE histogram — bar chart with standard normal N(0,1) overlay
NPDE Q-Q plot — quantile-quantile plot against standard normal
The NPDE column must be present in diagnostic_df. Use compute_npde() from openpkpd.plots.diagnostics to compute NPDEs from a fitted model.
- Parameters:
- Return type:
- Returns:
matplotlib.figure.Figure with 4 axes.
- Raises:
ImportError – If matplotlib is not installed.
ValueError – If the NPDE column is not found in diagnostic_df.
- openpkpd.plots.simulation.simulation_panel(simulated_df, observed_df=None, n_subjects=9, figsize=(15, 12), title='Simulated Profiles')[source]
Panel of simulated individual concentration-time profiles.
Shows up to n_subjects individual simulated profiles in a grid layout. Each panel displays all replicate profiles for that subject as thin translucent lines. If observed_df is provided, observed data points are overlaid as solid markers.
The simulated_df must contain columns: ID, TIME, DV, REP. The observed_df (optional) must contain columns: ID, TIME, DV.
- Parameters:
simulated_df (
Any) – DataFrame with simulated data (columns: ID, TIME, DV, REP). REP=0 is treated as the observed reference; REP>=1 are simulation replicates.observed_df (
Any|None) – Optional DataFrame with observed data (columns: ID, TIME, DV). If None, uses REP=0 rows from simulated_df if present.n_subjects (
int) – Maximum number of subjects to display (default 9).figsize (
tuple[float,float]) – Figure size (width, height) in inches.title (
str) – Overall figure title.
- Return type:
- Returns:
matplotlib.figure.Figure with a grid of individual profile panels.
- Raises:
ImportError – If matplotlib is not installed.
openpkpd.plots.vpc_plot is re-exported from the top-level openpkpd.plots
namespace as a convenience alias for
vpc_plot().