# Research directory

Author: Jaime Yan. Review date: 2026-09-21. **33 screened candidates; 12 targeted source/test inspections; five executed engines, three used in new templates.** These are different states, not a claim of 33 integrations.

Scope: purposive official-repository review seeded by the requested ecosystem plus missingness, uncertainty, genomics, quality control, causal diagrams, calibration and data-journalism tools. Geographic/spatial tools and systematic HCI user studies remain gaps. No popularity ranking. Pinned metadata and each candidate’s variables, risks, dependency declarations and status are in [catalog.json](catalog.json). Source snapshots are retained in ignored internal evidence; no third-party screenshots redistributed.

Pinned development HEADs below may differ from installed releases; measured versions are recorded separately. A source manifest does not resolve the transitive installation closure. Unknown assets/font rights block redistribution. This review is not legal advice or a package security audit.

| Project / inspected commit | Source license | Read / installed / run / verified / integrated | Decision |
|---|---|---|---|
| [pharmaverse](https://github.com/pharmaverse/pharmaverse/tree/7fca37b33ab2c35fbaea8c5f2aeff456ff2f00e9) `7fca37b33a` | Unresolved from retrieved files; no code adoption permitted | true / not-audited / false / false / false | Directory only; not an executable plotting dependency |
| [tern](https://github.com/pharmaverse/tern/tree/48f633f6c653a6fedb33241cdf13df440441f755) `48f633f6c6` | Apache License 2.0 | true / false / false / false / false | Reference g_lineplot; richer statistics tables than this extension, substantial clinical ecosystem dependencies |
| [rtables](https://github.com/pharmaverse/rtables/tree/c7d1a0d3def208046062894adff83b23cfe87bb4) `c7d1a0d3de` | Apache License 2.0 or file LICENSE | true / false / false / false / false | Design reference; hierarchical tables exceed our flat tables |
| [ggplot2](https://github.com/tidyverse/ggplot2/tree/4e886647b2dbc3f41a1dd072c063ce0455671cc2) `4e886647b2` | MIT + file LICENSE | true / true / true / true / true | Direct installed engine; native ggplot, mature scales and facets |
| [survival](https://github.com/therneau/survival/tree/ed1a6b249fa714ccb9169faea63ddafd1addb774) `ed1a6b249f` | LGPL (>=2) | true / true / false / false / false | Defer template; installed runtime is not integration |
| [ggsurvfit](https://github.com/pharmaverse/ggsurvfit/tree/a28afe991306baab3920b5ec70355c78c0624a3b) `a28afe9913` | MIT + file LICENSE | true / false / false / false / false | Defer until approved dependency/data; supports risk tables better than our templates |
| [gtsummary](https://github.com/ddsjoberg/gtsummary/tree/c6f5082334024f2c3b03c4bc9b65d5e97dde2fd9) `c6f5082334` | MIT + file LICENSE | true / not-audited / false / false / false | Design reference; many table exporters not needed for first slice |
| [admiral](https://github.com/pharmaverse/admiral/tree/06d5345b6a3f41083efd23015d0a84748b5c8e6b) `06d5345b6a` | Apache License (>= 2) | true / not-audited / false / false / false | Design reference; derivation is upstream of plotting |
| [forestly](https://github.com/Merck/forestly/tree/bdc340c8599a9d6c0fbb14eb9ba327e4c0f656fe) `bdc340c859` | GPL (>= 3) | true / not-audited / false / false / false | Defer; GPL source not vendored under custom noncommercial terms; inspect distribution before any future integration |
| [visR](https://github.com/openpharma/visR/tree/83198e41278e0e6d5aaeb7f74472922cdb6b72cd) `83198e4127` | MIT + file LICENSE | true / not-audited / false / false / false | Design reference; README maintenance boundary limits choosing it as new core |
| [Matplotlib](https://github.com/matplotlib/matplotlib/tree/615ff27caeeeb4934bf9164c51c92706a1cc95a0) `615ff27cae` | PSF-based Matplotlib license; official license page and pinned LICENSE/LICENSE | true / true / true / true / true | Direct installed engine; rich custom layout and output formats |
| [Seaborn](https://github.com/mwaskom/seaborn/tree/f04b6cd5484267a0885d1fed068e99dff3a1b226) `f04b6cd548` | BSD-family; inspect pinned text | true / true / true / true / false | Executed matched ECDF benchmark; simpler one-call grouping than our adapter |
| [Plotly](https://github.com/plotly/plotly.py/tree/0a13e2a4971a20d639d1c36b2b7a50cf39a03157) `0a13e2a497` | MIT | true / true / false / false / false | Installed status audited; not executed; native browser bundle/export dependencies need evaluation |
| [Altair](https://github.com/vega/altair/tree/b2ca919d5997abd8e3027ed2406e4e2dd342c789) `b2ca919d59` | BSD-3-Clause | true / true / false / false / false | Installed status audited; not executed; no Vega assets added |
| [Vega-Lite](https://github.com/vega/vega-lite/tree/831e308cf9feba791db0c279dea5f7983ca98445) `831e308cf9` | BSD-3-Clause | true / not-audited / false / false / false | Design only; retain Astro and exact precomputed selections |
| [Bokeh](https://github.com/bokeh/bokeh/tree/db1815de7044f5207d5a1bd7c2861cba65d2f604) `db1815de70` | BSD-3-Clause | true / false / false / false / false | Defer; no added backend or installation |
| [HoloViews](https://github.com/holoviz/holoviews/tree/ac770c0e05bb6cea9156f55d90ae19b158743853) `ac770c0e05` | BSD-3-Clause | true / false / false / false / false | Defer; new backend/dependency footprint unjustified for three simple views |
| [plotnine](https://github.com/has2k1/plotnine/tree/08e828c4bef5654f8dbff0684a8764c6af6a1294) `08e828c4be` | MIT-style; inspect pinned text | true / false / false / false / false | Defer; already have Matplotlib and native ggplot2 |
| [SciPy](https://github.com/scipy/scipy/tree/9b25efba554f5ca0fa00590a7b45ee118fbb8091) `9b25efba55` | BSD-family; inspect pinned text | true / true / true / true / true | Direct installed stats.ecdf and stats.t; tests/source reviewed |
| [statsmodels](https://github.com/statsmodels/statsmodels/tree/ddab271eb2ac6328f28b734752fd027a9f326f2a) `ddab271eb2` | BSD-3-Clause | true / true / true / true / false | Executed ECDF comparator; no template dependency added |
| [lifelines](https://github.com/CamDavidsonPilon/lifelines/tree/7a8fc34a013ecd79fa405017b89e1697c1cc6e17) `7a8fc34a01` | MIT-style; inspect pinned text | true / false / false / false / false | Defer; missing event inputs and unapproved dependencies |
| [scikit-survival](https://github.com/sebp/scikit-survival/tree/c09c04bcec9101d34ab9896fad2a6f6f3a353c42) `c09c04bcec` | GPL-3.0-or-later | true / false / false / false / false | Defer; compiled dependencies and no prediction input |
| [ggdist](https://github.com/mjskay/ggdist/tree/17c4698f3cf3b2d1a258edf0b144740849ed4ca6) `17c4698f3c` | GPL (>= 3) | true / false / false / false / false | Design only; richer half-eye/quantile-dot APIs; GPL source not copied |
| [ggridges](https://github.com/wilkelab/ggridges/tree/ddea131d7d266c09f99a0705c8f1adbcac4804f0) `ddea131d7d` | GPL-2 or file LICENSE | true / not-audited / false / false / false | Design only; ECDF avoids bandwidth for this small example |
| [DABEST](https://github.com/ACCLAB/DABEST-python/tree/ec6172724e0397bf0546863c76949d40da9c5457) `ec6172724e` | Apache-2.0 | true / false / false / false / false | Defer; estimation plot useful, no unsupported Gardner-Altman equivalence claim |
| [naniar](https://github.com/njtierney/naniar/tree/89f2a5df3743df02b6e601d403fa001fc8a79c79) `89f2a5df37` | MIT + file LICENSE | true / false / false / false / false | Design only; clinical not-due/death states need added semantics |
| [ComplexHeatmap](https://github.com/jokergoo/ComplexHeatmap/tree/ad11b26afe8c63dc05b20035503352ca740f602e) `ad11b26afe` | MIT + file LICENSE | true / not-audited / false / false / false | Design only; rich matrix annotations exceed current completion curve |
| [dagitty](https://github.com/jtextor/dagitty/tree/7a657776dc8f5e5ba4e323edb028e2c2aaf29327) `7a657776dc` | GPL; inspect pinned version | true / not-audited / false / false / false | Design only; GPL frontend not bundled; no browser data submission |
| [qcc](https://github.com/luca-scr/qcc/tree/e09918a0a02f4ff95859135943f8211a048e35a0) `e09918a0a0` | GPL (>= 2) | true / not-audited / false / false / false | Design only; avoid transplanting manufacturing alarm rules |
| [scikit-learn](https://github.com/scikit-learn/scikit-learn/tree/a5046923f202f84cc1617f4ea555431194c52836) `a5046923f2` | BSD-3-Clause | true / true / false / false / false | Design only; no model predictions in current data |
| [patchwork](https://github.com/thomasp85/patchwork/tree/6b1d88ce1da1c5cae3818d984edf80dc0bb3de8c) `6b1d88ce1d` | MIT + file LICENSE | true / not-audited / false / false / false | Design only; single-panel templates need no new dependency |
| [colorspace](https://github.com/cran/colorspace/tree/055c7d560a0bf9138bd30c9bf38d1a8323febe49) `055c7d560a` | BSD_3_clause + file LICENSE | true / not-audited / false / false / false | Design only; shape/line patterns and tables supplement colors |
| [Observable Plot](https://github.com/observablehq/plot/tree/535723d5e433727720d9b673c31622821bb03210) `535723d5e4` | ISC | true / not-audited / false / false / false | Design only; no extra JavaScript dependency |

## Twelve deeper inspections

### tern
g_lineplot documents means, medians, confidence levels and attached statistics tables. Tests address cohort IDs, facets and maintained factor levels. Our extension does not reproduce that breadth.
[tests/testthat/test-g_lineplot.R](https://github.com/pharmaverse/tern/blob/48f633f6c653a6fedb33241cdf13df440441f755/tests/testthat/test-g_lineplot.R); [man/g_lineplot.Rd](https://github.com/pharmaverse/tern/blob/48f633f6c653a6fedb33241cdf13df440441f755/man/g_lineplot.Rd); [R/g_lineplot.R](https://github.com/pharmaverse/tern/blob/48f633f6c653a6fedb33241cdf13df440441f755/R/g_lineplot.R)

### ggplot2
stat_ecdf tests cover weights, zero-sum/invalid weights and transformations. Our teaching contract is unweighted and deliberately narrower.
[tests/testthat/test-stat-ecdf.R](https://github.com/tidyverse/ggplot2/blob/4e886647b2dbc3f41a1dd072c063ce0455671cc2/tests/testthat/test-stat-ecdf.R); [tests/testthat/_snaps/stat-ecdf.md](https://github.com/tidyverse/ggplot2/blob/4e886647b2dbc3f41a1dd072c063ce0455671cc2/tests/testthat/_snaps/stat-ecdf.md); [R/stat-ecdf.R](https://github.com/tidyverse/ggplot2/blob/4e886647b2dbc3f41a1dd072c063ce0455671cc2/R/stat-ecdf.R)

### survival
survfit tests include hand-computed weighted risk sets and infinitesimal-jackknife variance. Missing PRO measurements must not be repurposed as event censoring.
[tests/survfit1.R](https://github.com/therneau/survival/blob/ed1a6b249fa714ccb9169faea63ddafd1addb774/tests/survfit1.R); [tests/survfit2.R](https://github.com/therneau/survival/blob/ed1a6b249fa714ccb9169faea63ddafd1addb774/tests/survfit2.R); [tests/survfit3.R](https://github.com/therneau/survival/blob/ed1a6b249fa714ccb9169faea63ddafd1addb774/tests/survfit3.R)

### ggsurvfit
add_risktable distinguishes n.risk, interval and cumulative events/censors and supports competing risks. Our fixed completion denominators have different semantics.
[tests/testthat/test-add_risktable.R](https://github.com/pharmaverse/ggsurvfit/blob/a28afe991306baab3920b5ec70355c78c0624a3b/tests/testthat/test-add_risktable.R); [tests/testthat/test-add_risktable_strata_symbol.R](https://github.com/pharmaverse/ggsurvfit/blob/a28afe991306baab3920b5ec70355c78c0624a3b/tests/testthat/test-add_risktable_strata_symbol.R); [man/add_risktable.Rd](https://github.com/pharmaverse/ggsurvfit/blob/a28afe991306baab3920b5ec70355c78c0624a3b/man/add_risktable.Rd)

### forestly
Tests cover embedded detail searches, risk-difference toggles and display-column choices. An excellent specialized AE candidate, pending data/license/distribution decisions.
[tests/testthat/test-ae_forestly.R](https://github.com/Merck/forestly/blob/bdc340c8599a9d6c0fbb14eb9ba327e4c0f656fe/tests/testthat/test-ae_forestly.R); [tests/testthat/helper-ae_forestly.R](https://github.com/Merck/forestly/blob/bdc340c8599a9d6c0fbb14eb9ba327e4c0f656fe/tests/testthat/helper-ae_forestly.R); [tests/testthat/test-format_ae_forestly.R](https://github.com/Merck/forestly/blob/bdc340c8599a9d6c0fbb14eb9ba327e4c0f656fe/tests/testthat/test-format_ae_forestly.R)

### visR
estimate_KM states CNSR=1 censor, removes missing analysis observations and defaults to log confidence limits. Future comparisons must explicitly align CI transformations.
[tests/testthat/test-estimate_KM.R](https://github.com/openpharma/visR/blob/83198e41278e0e6d5aaeb7f74472922cdb6b72cd/tests/testthat/test-estimate_KM.R); [man/estimate_KM.Rd](https://github.com/openpharma/visR/blob/83198e41278e0e6d5aaeb7f74472922cdb6b72cd/man/estimate_KM.Rd); [R/estimate_KM.R](https://github.com/openpharma/visR/blob/83198e41278e0e6d5aaeb7f74472922cdb6b72cd/R/estimate_KM.R)

### Matplotlib
The native Axes.ecdf example provides a minimal engine alternative. Our SciPy choice makes the calculated probabilities independently exportable before drawing.
[galleries/plot_types/stats/ecdf.py](https://github.com/matplotlib/matplotlib/blob/615ff27caeeeb4934bf9164c51c92706a1cc95a0/galleries/plot_types/stats/ecdf.py)

### Seaborn
Distribution implementation/tests and a faceted example were inspected; executed ecdfplot returns Axes and needs less plotting code. Complete-pair denominator metadata is application work.
[tests/test_distributions.py](https://github.com/mwaskom/seaborn/blob/f04b6cd5484267a0885d1fed068e99dff3a1b226/tests/test_distributions.py); [seaborn/distributions.py](https://github.com/mwaskom/seaborn/blob/f04b6cd5484267a0885d1fed068e99dff3a1b226/seaborn/distributions.py); [examples/large_distributions.py](https://github.com/mwaskom/seaborn/blob/f04b6cd5484267a0885d1fed068e99dff3a1b226/examples/large_distributions.py)

### SciPy
The ECDF implementation includes survival and Greenwood interval paths. We execute only uncensored ECDF and t quantiles; unused capability is not claimed as validated.
[scipy/stats/tests/test_survival.py](https://github.com/scipy/scipy/blob/9b25efba554f5ca0fa00590a7b45ee118fbb8091/scipy/stats/tests/test_survival.py); [scipy/stats/_survival.py](https://github.com/scipy/scipy/blob/9b25efba554f5ca0fa00590a7b45ee118fbb8091/scipy/stats/_survival.py)

### statsmodels
Empirical-distribution source provides right/left step conventions, weighted discrete distributions and DKW bands. Our right-continuous comparator matches exact complete-pair probabilities.
[statsmodels/distributions/empirical_distribution.py](https://github.com/statsmodels/statsmodels/blob/ddab271eb2ac6328f28b734752fd027a9f326f2a/statsmodels/distributions/empirical_distribution.py)

### ggdist
Tests inspect constant distributions, missing slab thickness, orientation and normalization. Distribution semantics must be selected before borrowing half-eye aesthetics; no GPL code copied.
[tests/testthat/test.rd_slabinterval.R](https://github.com/mjskay/ggdist/blob/17c4698f3cf3b2d1a258edf0b144740849ed4ca6/tests/testthat/test.rd_slabinterval.R); [tests/testthat/test.geom_slabinterval.R](https://github.com/mjskay/ggdist/blob/17c4698f3cf3b2d1a258edf0b144740849ed4ca6/tests/testthat/test.geom_slabinterval.R); [tests/testthat/test.stat_slabinterval.R](https://github.com/mjskay/ggdist/blob/17c4698f3cf3b2d1a258edf0b144740849ed4ca6/tests/testthat/test.stat_slabinterval.R)

### naniar
gg_miss_var documents counts/proportions and facets; cumulative-missing plots are different from scheduled-visit eligibility. We borrow the question, not its implementation.
[man/gg_miss_var.Rd](https://github.com/njtierney/naniar/blob/89f2a5df3743df02b6e601d403fa001fc8a79c79/man/gg_miss_var.Rd); [man/gg_miss_var_cumsum.Rd](https://github.com/njtierney/naniar/blob/89f2a5df3743df02b6e601d403fa001fc8a79c79/man/gg_miss_var_cumsum.Rd)

## Additional primary documentation and papers

- [SciPy ECDF reference](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ecdf.html) and [ggplot2 ECDF reference](https://ggplot2.tidyverse.org/reference/stat_ecdf.html).
- [Seaborn ECDF reference and examples](https://seaborn.pydata.org/generated/seaborn.ecdfplot.html): direct cumulative proportions avoid bins; unfamiliar shapes require teaching.
- Tierney and Cook, [Expanding Tidy Data Principles to Facilitate Missing Data Exploration, Visualization and Assessment of Imputations](https://www.jstatsoft.org/article/view/v105i07): missingness exploration informs the completion case, not identification of its mechanism.
- Wickham, [Tidy Data](https://www.jstatsoft.org/article/view/v059i10): explicit subject/domain/time keys support independent calculation.
- [Vega-Lite selection parameters](https://vega.github.io/vega-lite/docs/selection.html): separates selection from transforms; our UI uses exact precomputed strata.
- [W3C complex-image guidance](https://www.w3.org/WAI/tutorials/images/complex/): text descriptions and adjacent data tables; implementation still requires browser testing.
- [pharmaverse directory](https://pharmaverse.org/) and [visR maintenance statement](https://openpharma.github.io/visR/).

Failed initial web retrievals: ggsurvfit gallery and ggdist slabinterval article. Pinned repository manuals/tests were used instead. No upstream package was installed for this work. No source, example image, font or dataset was re-licensed as Jaime Yan material.

License discrepancy: DABEST README badge differs from its pinned Apache-2.0 manifest/LICENSE; no implementation copied. See catalog.json.

The 31-page naniar paper was subsequently retrieved and its missingness, software/exploration and shadow-matrix sections inspected; provenance is in paper-provenance.json. Its PDF is internal evidence only.

## Subsequent adoption update

Statsmodels 0.14.6 is now integrated through the complete-case ANCOVA adapter, independently checked against R lm and an analytic orthogonal fixture. The earlier screening commit differs from the executed installed release; source/license SHA-256 and the changed adoption state are in catalog.json. The catalog review is AI-agent inspection, not human external evaluation.
