# Import necessary libraries
import sys
import numpy as np
import pandas as pd
import pyfixest as pf
import statsmodels.formula.api as smf
# Force reload of maketables module - delete ALL maketables modules
mods_to_del = [k for k in sys.modules.keys() if 'maketables' in k]
for mod in mods_to_del:
del sys.modules[mod]
import maketables as mt
# Load sample dataset
df = pd.read_csv("../data/salaries.csv")
# Set variable labels
labels = {
"logwage": "ln(Wage)",
"wage": "Wage",
"age": "Age",
"female": "Female",
"tenure": "Years of Tenure",
"occupation": "Occupation",
"worker_type": "Worker Type",
"education": "Education Level",
"promoted": "Promotion"
}
# Set default labels
mt.MTable.DEFAULT_LABELS = labels
# Generate a categorical variable for gender from the dummy variable
df["gender"] = df["female"].map({0: "Male", 1: "Female"})Generating Typst Tables
Overview
Typst is a typesetting system that offers an alternative to LaTeX. A key advantage is that it offers extremely fast compiling. This notebook demonstrates how to generate publication-quality tables in Typst format using maketables.
An Example Document
Here you see the pdf of a typst document generated by the code explained in the end of this notebook:
Setup and Data Preparation
First, let’s load the necessary libraries and prepare the data:
Generating Tables
Create a descriptive statistics table:
# Create descriptive statistics table
tab1 = mt.DTable(df, vars=["wage", "age", "tenure"],
bycol=["worker_type"], byrow="gender",
stats=["count", "mean", "std"],
caption="Descriptive statistics by worker type and gender",
tab_label="tab:descriptives",
format_spec={'mean': ',.2f', 'std': '.2f'})
# Save as Typst
tab1.save(type="typst", file_name="../output/table1_descriptives.typ", show=False, replace=True)Create the wage regression table using PyFixest’s stepwise notation:
# Create regression table using PyFixest
tab2 = mt.ETable(pf.feols("logwage+wage ~ age + female + sw0(age:female)", data=df),
caption="Wage regressions",
tab_label="tab:regressions")
# Save as Typst
tab2.save(type="typst", file_name="../output/table2_regressions.typ", show=False, replace=True)Now use Statsmodels for an OLS and Probit comparison:
# Fit models for promotion prediction
est1 = smf.ols("promoted ~ tenure + female + worker_type", data=df).fit()
est2 = smf.probit("promoted ~ tenure + female + worker_type", data=df).fit(disp=0)
# Create comparison table
tab3 = mt.ETable([est1, est2],
keep=["tenure", "female", "worker_type"],
model_stats=["N", "r2", "pseudo_r2"],
model_heads=["OLS", "Probit"],
caption="Predicting Promotions",
tab_label="tab:promotions")
# Save as Typst
tab3.save(type="typst", file_name="../output/table3_promotions.typ", show=False, replace=True)Output Style and Defaults
You can customize table appearance by modifying the DEFAULT_TYPST_STYLE dictionary. Key parameters include:
first_col_width: Width of the first column (default"auto"- adapts to content)column_gutter: Space between columns (default"0.5em"at MultiIndex transitions)group_header_format: Format for group headers (default"%s"- plain text)notes_font_size: Font size for notes (default"10pt")rgroup_sep: Row group separators -"t"(top),"b"(bottom),"tb"(both), or""(none)
Example customization:
# Adjust styling and formatting for Typst
mt.MTable.DEFAULT_TYPST_STYLE.update({
"first_col_width": "auto", # Auto-size to content width
"notes_font_size": "9pt", # Smaller notes
"group_header_format": "*%s*", # Bold group headers
})Column Width Control
Control the first column width in Typst tables:
- Default (
"auto"): First column adapts to the widest row label, data columns share remaining space equally - Fixed width: Set
first_col_widthto a specific value like"3cm","2in", or"150pt"
Example with explicit width:
# Create table with explicit first column width
tab1_fixed = mt.DTable(df, vars=["wage", "age", "tenure"],
bycol=["worker_type"], byrow="gender",
stats=["count", "mean", "std"],
caption="Descriptive statistics (fixed column width)",
format_spec={'mean': ',.2f', 'std': '.2f'})
# Save with explicit first column width
tab1_fixed.save(type="typst", file_name="../output/table1_descriptives_fixed_width.typ",
show=False, replace=True,
typst_style={"first_col_width": "2.5cm"})Typst Integration
To use these Typst tables in your documents, reference them using Typst’s include statement:
#include "table1_descriptives.typ"Or embed directly in your Typst document source. For more information, see typst.app
Combined Typst Document
You can also use the update_typst method to create a single Typst file containing all tables. With this method you can also update table content in an existing Typst document. The method checks whether a table with the same label already exists in the document and replaces it if found; otherwise, it appends the new table at the end of the document.
# Create or update a comprehensive Typst document using update_typst
output_path = "../output/TypstOutput.typ"
# Base document with section headers and narrative text
typst_header = """#set page(paper: "a4")"""
with open(output_path, "w", encoding="utf-8") as f:
f.write(typst_header)
# Insert or replace tables by label
tab1.update_typst(file_name=output_path, tab_label="tab:descriptives")
tab2.update_typst(file_name=output_path, tab_label="tab:regressions")
tab3.update_typst(file_name=output_path, tab_label="tab:promotions")