Python table formatting with great-tables: publication-quality display tables from Polars/pandas DataFrames. GT() grammar-of-tables object, fmt_*() number formatting, tab_*() structure (header, spanners, stub, source notes), tab_style() and data_color() styling, cols_*() column operations, and HTML/LaTeX export via as_raw_html()/write_raw_html()/as_latex(). Use when execution language is Python and the task involves formatted data tables, summary tables, or descriptive-stat tables for reports...
235 stars
0 votes
0 copies
3 views
Added September 12, 2026
researchpythongobashexpressgitapi
Works with
api
Security analysis
A92/100
mediumInstalls packages at runtime which could introduce malicious dependencies
Installs into .claude/skills of the current project.
Are you the author of Great Tables?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/daaf-contribution-community-great-tables)
---
name: great-tables
description: >-
Python table formatting with great-tables: publication-quality display tables
from Polars/pandas DataFrames. GT() grammar-of-tables object, fmt_*() number
formatting, tab_*() structure (header, spanners, stub, source notes), tab_style()
and data_color() styling, cols_*() column operations, and HTML/LaTeX export via
as_raw_html()/write_raw_html()/as_latex(). Use when execution language is Python
and the task involves formatted data tables, summary tables, or descriptive-stat
tables for reports. R equivalent: gt (use when execution language is R). For
regression/model tables in Python, use the estimator's own output (pyfixest
etable(), statsmodels summary()) — great-tables has no modelsummary equivalent.
For figures/charts use plotnine or plotly, not this skill.
metadata:
audience: research-coders
domain: python-library
library-version: "0.21.0"
skill-last-updated: "2026-07-13"
---
# Great Tables Skill
great-tables is the Python implementation of the **grammar of tables** — the same
grammar as R's gt, by the same author (Rich Iannone, Posit). It builds
publication-quality display tables declaratively by layering formatting, structure,
and style onto a `GT()` object. Use when execution language is Python and the task
involves creating formatted data tables, cross-tabulations, or descriptive-statistics
tables for reports and papers. great-tables accepts Polars DataFrames natively (DAAF's
default) as well as pandas. For figures use `plotnine` (static) or `plotly`
(interactive); for regression/model comparison tables great-tables has no
modelsummary-style helper, so use the estimator's own tabular output instead
(pyfixest `etable()`, statsmodels `.summary()`). R counterpart: the `gt` skill —
substitute it when execution language is R.
## What is great-tables?
great-tables implements a **grammar of tables**, analogous to plotnine/ggplot2's
grammar of graphics but for tabular output:
- **Declarative**: build tables by chaining formatting, structure, and style methods
- **Method-chaining**: every method returns a new `GT` object, so operations chain
with `.` (Python) rather than R's `|>` pipe
- **Rich formatting**: `fmt_number`, `fmt_percent`, `fmt_currency`, `fmt_date`,
`fmt_markdown`, conditional styling, color scales
- **Structured**: header (title/subtitle), column spanners, row-group stub,
grand summary rows, source notes, footnotes
- **DataFrame-native**: pass a Polars DataFrame directly to `GT()` (pandas also
accepted; Polars is the DAAF default)
**Probe-verified against installed 0.21.0** (2026-07-13): all API claims in this
skill and its references were executed against the package. Version-specific caveats
(e.g., `grand_summary_rows` expecting Polars expressions, `cols_merge` 0-based
indices, `save()` needing selenium) are documented at their point of use.
## Version Notes (0.21.0)
- **Canonical constructor is `gt.GT(df)`.** The `GT.from_data()` classmethod is
broken in 0.21.0 (raises `TypeError` on an internal `_tbl_data` kwarg) — do not
use it. Probe: `04_extras_a.py` in the R_Support sessionF scratch.
- **`grand_summary_rows(fns=...)` expects Polars expressions**, not R-style string
aggregator names. Use `{"Total": pl.all().sum()}`, not `{"Total": "sum"}`. It also
does **not** support the `columns=` selection argument in 0.21.0 (raises
`NotImplementedError`) — summaries apply across all numeric columns.
- **`cols_merge(pattern=...)` uses 0-based `{0}`, `{1}` indices** — differs from R
gt's 1-based `{1}`, `{2}`.
- **HTML and LaTeX export work in-process** (`as_raw_html`, `write_raw_html`,
`as_latex`) — no external dependency.
- **Image export (`save()` to PNG/PDF) does NOT work in the DAAF container** — it
requires `selenium` + a headless Chrome driver, neither of which is installed
(and runtime `pip install` is blocked by DAAF policy). Export tables as HTML
instead. See `./references/export.md`.
## How to Use This Skill
### Reference File Structure
| File | Purpose | When to Read |
|------|---------|--------------|
| `quickstart.md` | GT() from a Polars DataFrame, header/source notes, basic fmt_* formatting | Starting out or need a quick table |
| `formatting-structure.md` | Full fmt_* family, tab_style/data_color styling, spanners, row-group stub, grand summary rows, cols_* operations | Detailed formatting and structure |
| `export.md` | as_raw_html/write_raw_html/as_latex, the save() image limitation, saving into project outputs | Saving or embedding tables |
### Reading Order
1. **Quick data table?** Start with `quickstart.md`
2. **Complex formatting or structure?** Read `formatting-structure.md`
3. **Saving or embedding a table?** Read `export.md`
## Related Skills
| Skill | Relationship |
|-------|-------------|
| `gt` | R counterpart — same grammar of tables. Use `gt` when execution language is R; use great-tables when Python |
| `polars` | DAAF's default DataFrame library — great-tables accepts Polars DataFrames directly; build/aggregate the data in Polars, then format with great-tables |
| `plotnine` | Static figures (charts/plots) — use plotnine for figures, great-tables for tables |
| `plotly` | Interactive figures — use plotly for interactive charts, great-tables for tables |
| `pyfixest` | Regression output — great-tables has no modelsummary equivalent; use pyfixest `etable()` for FE/DiD model tables |
| `statsmodels` | Regression output — use statsmodels `.summary()` / `summary2()` for model tables |
| `data-scientist` | Methodology guidance for what to present in tables |
**R counterpart:** For R pipelines, use the `gt` skill instead. great-tables and gt
share the grammar of tables but differ in surface details (method chaining vs `|>`,
0-based vs 1-based `cols_merge` indices, Polars-expression vs string aggregators in
summary rows, and export capabilities — see Version Notes).
## Quick Decision Trees
### "I need to make a table"
```
What kind of table?
├─ Data summary table (descriptive stats, crosstabs)
│ ├─ Simple (few rows/columns, minimal formatting)
│ │ └─ GT() + fmt_* → ./references/quickstart.md
│ └─ Complex (conditional styling, row groups, summary rows, color scales)
│ └─ tab_style / data_color / grand_summary_rows → ./references/formatting-structure.md
├─ Frequency / cross-tabulation table
│ └─ GT() with groupname_col row-group stub → ./references/formatting-structure.md
├─ Regression / model-coefficient table
│ └─ great-tables has NO modelsummary equivalent. Use the estimator's own output:
│ pyfixest etable() (FE/DiD) or statsmodels .summary() — see those skills
└─ Table with color scales or conditional formatting
└─ data_color() or tab_style() → ./references/formatting-structure.md
```
### "How do I save or embed it?"
```
Output target?
├─ HTML string (embed in a report, session workspace) → as_raw_html() → ./references/export.md
├─ HTML file on disk → write_raw_html() → ./references/export.md
├─ LaTeX (journal submission) → as_latex() → ./references/export.md
└─ PNG/PDF image → NOT available in the container (needs selenium/headless Chrome).
Export HTML instead → ./references/export.md
```
## File-First Execution in Research Workflows
In DAAF research pipelines, tables are generated through **script files** in
`scripts/stage8_analysis/`, not interactively. This ensures auditability and
reproducibility.
**The pattern:**
1. Write table code to `scripts/stage8_analysis/{step}_{table-name}.py`
2. Execute via `bash {BASE_DIR}/scripts/run_with_capture.sh {script_path}`
3. Output gets appended to the script as comments
4. Use `write_raw_html()` (or `as_raw_html()` + write) to save tables into the
project output directory as HTML
See `agent_reference/SCRIPT_EXECUTION_REFERENCE.md` for the mandatory file-first
execution protocol.
## Quick Reference
### Essential Setup
```python
import polars as pl
import great_tables as gt
from great_tables import loc, style, md
```
### Basic GT Table (from a Polars DataFrame)
```python
tbl = (
gt.GT(df, rowname_col="region", groupname_col="group")
.tab_header(title="Revenue by Region", subtitle="FY2025")
.tab_source_note(source_note=md("Source: *synthetic data*"))
.fmt_currency(columns="revenue", currency="USD", decimals=2)
.fmt_percent(columns="share", decimals=1)
.cols_label(revenue="Revenue", share="Share")
)
html = tbl.as_raw_html()
```
### Core GT Operations
| Operation | Code |
|-----------|------|
| Create table (Polars or pandas) | `gt.GT(df)` |
| Row-group stub | `gt.GT(df, rowname_col="id", groupname_col="grp")` |
| Title/subtitle | `.tab_header(title=..., subtitle=...)` |
| Source note | `.tab_source_note(source_note=md("Source: ..."))` |
| Stubhead label | `.tab_stubhead(label="...")` |
| Format numbers | `.fmt_number(columns=..., decimals=2)` |
| Format percent | `.fmt_percent(columns=..., decimals=1)` |
| Format currency | `.fmt_currency(columns=..., currency="USD")` |
| Format date | `.fmt_date(columns=..., date_style=...)` |
| Markdown in cells | `.fmt_markdown(columns=...)` |
| Column spanner | `.tab_spanner(label="...", columns=[...])` |
| Grand summary rows | `.grand_summary_rows(fns={"Total": pl.all().sum()})` |
| Missing-value text | `.sub_missing(missing_text="--")` |
| Conditional style | `.tab_style(style=style.fill(color="..."), locations=loc.body(...))` |
| Color scale | `.data_color(columns=[...], palette=["white", "blue"])` |
| Column labels | `.cols_label(col="Label")` |
| Column align | `.cols_align(align="right", columns=[...])` |
| Hide columns | `.cols_hide(columns=[...])` |
| Merge columns | `.cols_merge(columns=["lo","hi"], pattern="{0}–{1}")` |
| Column width | `.cols_width({"col": "150px"})` |
| Export HTML string | `.as_raw_html()` |
| Write HTML file | `.write_raw_html("table.html")` |
| Export LaTeX | `.as_latex()` |
### Format Scalar Values (no table)
```python
from great_tables import vals
vals.fmt_number([1234.5, 6789.0], decimals=1) # ['1,234.5', '6,789.0']
```
## Topic Index
| Topic | Reference File |
|-------|---------------|
| GT() from Polars/pandas | `./references/quickstart.md` |
| tab_header, tab_source_note, tab_stubhead | `./references/quickstart.md` |
| Basic fmt_number / fmt_percent / fmt_currency | `./references/quickstart.md` |
| cols_label column renaming | `./references/quickstart.md` |
| Full fmt_* family (date, markdown, integer, scientific, bytes) | `./references/formatting-structure.md` |
| Conditional styling (tab_style, loc, style) | `./references/formatting-structure.md` |
| Color scales (data_color) | `./references/formatting-structure.md` |
| Column spanners (tab_spanner) | `./references/formatting-structure.md` |
| Row-group stub (groupname_col, row_group_order) | `./references/formatting-structure.md` |
| Grand summary rows (Polars expressions) | `./references/formatting-structure.md` |
| sub_missing / sub_zero | `./references/formatting-structure.md` |
| Column operations (align, hide, move, merge, width) | `./references/formatting-structure.md` |
| Table options (opt_*, tab_options) | `./references/formatting-structure.md` |
| as_raw_html / write_raw_html | `./references/export.md` |
| as_latex | `./references/export.md` |
| save() image limitation (selenium) | `./references/export.md` |
| Saving into project outputs | `./references/export.md` |
## Citation
When great-tables is used as a primary table-formatting tool, include in the
report's Software & Tools references:
> Iannone, R., & Chow, M. (2024). great-tables: Easily generate information-rich,
> publication-quality tables from Python. Python package version 0.21.0.
> https://posit-dev.github.io/great-tables/
**Cite when:** great-tables produces tables included in the report or deliverables.
**Do not cite when:** only used for quick exploratory tables not included in
deliverables.