Core types¶
The frozen dataclass surface every renderer consumes.
SofraTable
dataclass
¶
SofraTable(rows: tuple[Row, ...] = (), headers: tuple[HeaderRow, ...] = (), spanning_headers: tuple[SpanningHeader, ...] = (), caption: str | None = None, footnotes: tuple[str, ...] = (), theme_name: str = 'default', metadata: dict[str, Any] = dict(), inline_svg: str | None = None, inline_svg_position: str = 'above', inline_plot: Any = None, _spec: TableSpec | None = None, _rebuild: RebuildFn | None = None)
A backend-agnostic publication-ready table.
Attributes:
| Name | Type | Description |
|---|---|---|
rows |
tuple[Row, ...]
|
The table body, one :class: |
headers |
tuple[HeaderRow, ...]
|
Column header rows, top-to-bottom. Most tables have a single header row; multi-level headers are supported via additional rows. |
spanning_headers |
tuple[SpanningHeader, ...]
|
Optional spanning headers above the column headers. |
caption |
str | None
|
Optional table caption (rendered as a title above the table). |
footnotes |
tuple[str, ...]
|
Tuple of footnote strings rendered below the table. |
theme_name |
str
|
Theme key registered in :mod: |
metadata |
dict[str, Any]
|
Free-form metadata dict carried for downstream consumers and tests (e.g. raw p-values, SMDs, model objects). |
theme ¶
Apply a theme by name. See :mod:pysofra.themes for available themes.
set_caption ¶
Set the table caption, replacing any existing one.
The caption renders above the table in every backend
(<caption> in HTML, \caption{} in LaTeX, a bold
paragraph above the table in DOCX/PPTX, sheet header in
XLSX). Pass None to clear an existing caption.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str | None
|
The caption string, or |
required |
Returns:
| Type | Description |
|---|---|
SofraTable
|
A new SofraTable with the caption set. The original is unchanged. |
add_footnote ¶
Append a single footnote to the existing footnote list.
Footnotes render below the table in every backend, in the
order they were appended. Builders such as :func:tbl_one
emit footnotes automatically (e.g. "Tests:", "n (%) for
categorical variables.") describing test choices and
formatting; user-supplied footnotes appended via this method
appear after the auto-generated ones.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The footnote text. Plain text; renderers escape special characters appropriately for their backend. |
required |
Returns:
| Type | Description |
|---|---|
SofraTable
|
A new SofraTable with the footnote appended. To replace
the footnote list wholesale, use
:meth: |
with_footnotes ¶
Replace the footnote list entirely.
add_p ¶
Add a p-value column.
Behaviour depends on the builder that produced the table. For
tbl_one / tbl_summary this triggers automatic test
selection per row (see :mod:pysofra.summary.tests); for
tbl_regression p-values are already present and this is a
no-op.
add_q ¶
Add a multiplicity-adjusted q-value column.
method is passed through to
statsmodels.stats.multitest.multipletests; common choices are
fdr_bh (Benjamini–Hochberg, default), fdr_by,
bonferroni, holm, hommel, sidak. Implicitly
enables p-values when not already on.
References
Benjamini, Y., & Hochberg, Y. (1995). Controlling the false
discovery rate: a practical and powerful approach to multiple
testing. J. R. Stat. Soc. B, 57(1), 289–300. (fdr_bh)
Benjamini, Y., & Yekutieli, D. (2001). The control of the
false discovery rate in multiple testing under dependency.
Ann. Stat., 29(4), 1165–1188. (fdr_by)
Holm, S. (1979). A simple sequentially rejective multiple test
procedure. Scand. J. Stat., 6(2), 65–70. (holm)
Hommel, G. (1988). A stagewise rejective multiple test
procedure based on a modified Bonferroni test. Biometrika,
75(2), 383–386. (hommel)
Šidák, Z. (1967). Rectangular confidence regions for the
means of multivariate normal distributions. J. Am. Stat.
Assoc., 62(318), 626–633. (sidak)
add_significance_stars ¶
add_significance_stars(*, thresholds: tuple[tuple[float, str], ...] = ((0.001, '***'), (0.01, '**'), (0.05, '*'))) -> SofraTable
Append a stars column with *** / ** / * significance markers.
thresholds is a tuple of (cutoff, marker) pairs sorted
smallest-cutoff first; each p-value is marked with the first
marker whose cutoff it falls below.
add_stat_label ¶
Append a Statistic column describing each row's summary form.
color_scale_if ¶
color_scale_if(*, column: int, palette: tuple[str, str, str] = ('#fff5f0', '#fcae91', '#cb181d'), skip_blank: bool = True) -> SofraTable
Heatmap-style cell colouring for one numeric column (HTML only).
add_global_p ¶
Add a joint Type-III p-value column.
Supported on both :func:tbl_regression and
:func:tbl_one / :func:tbl_summary tables, via two paths:
- tbl_regression — for each multi-level categorical
predictor in the model, the joint Wald-F p-value is
computed via
model.f_teston the contrast matrix that zeroes out every level simultaneously. Single-level coefficients receive their existing p-value duplicated. - tbl_one / tbl_summary — for each variable in the table,
a logistic regression is fit on the source data:
Logit(by == reference_level ~ variable [+ adjust_for]). The joint Wald p-value across the variable's coefficients is the new "global p" cell. Adjustment covariates passed viaadjust_for=apply to every variable's fit, giving covariate-adjusted joint p-values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
adjust_for
|
list[str] | tuple[str, ...] | None
|
(tbl_one / tbl_summary only) Optional list of covariate
column names to include in each per-variable regression.
Continuous numeric covariates enter as-is; non-numeric
covariates are dummy-coded. Ignored on
:func: |
None
|
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
On composition primitives ( |
add_difference ¶
Add a between-group difference column (continuous + dichotomous).
Requires a 2-group Table 1. Continuous rows get the Welch
mean-difference + CI; dichotomous rows get the proportion
difference with Wilson-score-based CI; multi-level categorical
rows show —.
add_ci ¶
Append a confidence interval to each summary cell.
Continuous cells gain [lo, hi] for the mean; dichotomous
cells gain [lo%, hi%] for the proportion (Wilson score).
with_pvalue_fmt ¶
Re-format every p-value cell with the supplied callable.
with_estimate_fmt ¶
Re-format every numeric estimate cell with the supplied callable.
autofit ¶
Hint every renderer to size columns to content.
Stored as metadata['autofit']. HTML uses content-based sizing
natively; XLSX auto-sizes column widths to the widest cell; the
DOCX renderer sets table.autofit = True when this flag is on.
compose ¶
Replace a cell's content with multiple typographically distinct parts.
parts is an iterable of :class:~pysofra.core.schema.CellPart
— each carries its own bold / italic / superscript /
subscript / color / link flags. Renderers concatenate
the parts inside the same cell, honouring whichever flags the
backend supports; the fallback text is set to the
concatenated plain text so non-rich backends still print
something readable.
modify_spanning_header ¶
Add (or replace at the same range) a spanning header above columns.
Columns are 0-indexed and the range is inclusive on both ends. Overlapping a previous span removes it.
inline_text ¶
Pull the text of a single cell for inline use.
row and column accept either a 0-indexed integer or a
string matched against the first cell of each row / each header
cell text. Raises KeyError if no match is found.
to_image ¶
Render the table to a PNG image.
Uses matplotlib under the hood; the result is a faithful raster of the HTML output. Useful for quick previews, Slack attachments, and document figures where a static image is preferable.
scale multiplies the pixel density (>= 1 recommended);
dpi controls the output resolution (defaults to 300, the
usual print-quality target).
add_overall ¶
Add an overall (unstratified) column.
bold_p ¶
Bold rows whose p-value cell carries a value below threshold.
This is a presentational modifier — it works on any SofraTable
whose body rows contain a cell of kind p_value with a numeric
value.
bold_if ¶
Bold every cell of rows satisfying predicate(row) -> bool.
Example::
table.bold_if(lambda r: r.cells[0].text.startswith('age'))
highlight_if ¶
Highlight rows (background colour) satisfying predicate.
Adds an html_style metadata entry consumed by the HTML
renderer; ignored by Markdown / LaTeX. color accepts any CSS
colour string.
style_if ¶
style_if(predicate: Callable[[Row], bool], *, bold: bool = False, italic: bool = False, color: str | None = None) -> SofraTable
General-purpose conditional row styling.
Combines :meth:bold_if, italic toggling, and an optional row
background highlight in one call.
to_html ¶
Render the table as a standalone HTML fragment.
sticky_header=True keeps the column headers in view as the
body scrolls — pair with max_height (a CSS length like
"60vh" or "400px") to enable the vertical scroll
container.
to_docx ¶
Write the table to a .docx file. Returns the resolved path.
to_latex ¶
Render the table as a LaTeX table float (booktabs by default).
Requires \usepackage{booktabs} in the consumer document
preamble. Returns the LaTeX source as a string; write it to a
.tex file with :func:pathlib.Path.write_text if needed.
Inline plots are embedded only when using :meth:to_latex_file
(which writes a sidecar PDF). For a plain LaTeX string call this
method and ignore any attached plot.
to_latex_file ¶
to_latex_file(path: str | Path, *, booktabs: bool = True, float_position: str = 'ht', centering: bool = True) -> Path
Write a .tex file plus a sidecar PDF for any inline plot.
If the table carries an :class:~pysofra.plot.InlinePlot, the
plot is written as <stem>_plot.pdf next to the .tex file
and embedded with \includegraphics. Requires graphicx in
the consuming document preamble.
to_pptx ¶
Write the table to a single-slide .pptx file.
Requires the optional python-pptx dependency
(pip install pysofra[pptx]). If slide_title is omitted,
the table's caption is used.
to_xlsx ¶
Write the table to an .xlsx file via xlsxwriter.
to_quarto ¶
Render the table as a Quarto-fenced block.
Quarto (https://quarto.org) is the dominant reproducible-
research authoring framework across Python and R. A Quarto
block emitted here can be include-d directly in a .qmd
document and Quarto will render it natively for the target
output format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
format
|
str
|
One of |
'html'
|
label
|
str | None
|
Optional Quarto cross-reference label of the form
|
None
|
caption
|
str | None
|
Optional caption text. When |
None
|
Returns:
| Type | Description |
|---|---|
str
|
A Quarto-source string ready to paste into a |
to_typst ¶
Render the table as Typst markup.
Typst (https://typst.app/) is a modern document-preparation
system positioned as a faster, simpler alternative to LaTeX.
The returned string is a #table(...) block ready to paste
into a .typ document.
to_typst_file ¶
Write the table to a .typ file (Typst source).
snapshot_hash ¶
SHA-256 of the table's logical content (Markdown + footnotes).
See :mod:pysofra.core.snapshot for the precise content
policy.
lock_snapshot ¶
Write a snapshot lock file pinning this table's content.
Use assert_snapshot later (in CI, in unit tests, in the
analysis script's smoke check) to verify the table hasn't
drifted from the pinned version.
assert_snapshot ¶
Raise AssertionError if the table differs from path.
The error message includes a unified diff between the pinned content and the current content, so the author can see exactly which row / footnote / spanning header changed.
check_safety ¶
Scan the table for retraction-prone patterns.
Returns a list of
:class:pysofra.core.safety.SafetyWarning objects describing
any flagged rows (extreme proportions, suspect SDs, sparse-
cell p-values, extreme effect sizes, dominant missingness).
An empty list means no flags.
with_safety_warnings ¶
Append a "Safety warnings" footnote summarising flagged rows.
Equivalent to::
for w in t.check_safety():
t = t.with_footnote(f"SAFETY: {w}")
Use this in published-analysis scripts so the rendered table carries the diagnostic flags into the paper alongside the numbers.
with_inline_svg ¶
Attach a raw inline-SVG string to this table.
The HTML renderer embeds the SVG above (default) or below the
table. Markdown ignores the SVG (no in-line image syntax for
SVG strings). For a plot that needs to travel through DOCX /
LaTeX / PPTX as well, use :meth:with_forest_plot or
:meth:with_km_plot instead — those serialise a matplotlib
figure into SVG + PNG + PDF and each renderer picks the
format it supports.
with_forest_plot ¶
with_forest_plot(*, log_x: bool | None = None, null_line: float | None = None, position: str = 'above', **plot_kwargs: Any) -> SofraTable
Attach a forest plot rendered from this regression table's coefficients.
Only valid for tables produced by :func:tbl_regression. Reads
the point estimate + CI cells directly from the table body so
the plot is guaranteed to match the displayed numbers. The
attached plot carries SVG / PNG / PDF serialisations so it
embeds in HTML, DOCX, PPTX, and LaTeX output consistently.
log_x and null_line default to None and are
auto-detected from the table's coefficient column header:
exponentiated families (OR / HR / TR / IRR / RR) get
log_x=True, null_line=1.0; raw-coefficient families
(β / Estimate) get log_x=False, null_line=0.0. Pass an
explicit value to override.
with_km_plot ¶
Attach a Kaplan–Meier curve to a :func:tbl_survival result.
Refits the KM curves from the original data using lifelines
and embeds SVG + PNG + PDF serialisations so the same plot
renders in HTML, DOCX, PPTX, and LaTeX exports.
CellPart
dataclass
¶
CellPart(text: str, bold: bool = False, italic: bool = False, superscript: bool = False, subscript: bool = False, code: bool = False, color: str | None = None, link: str | None = None)
A typographically distinct run inside a single cell.
Used by SofraTable.compose() to embed multi-format content
(bold + italic + colour) inside one cell. Renderers honour
CellPart.bold, italic, superscript, subscript,
code, color, and link where the backend supports them;
unsupported flags degrade to plain text.