Publication-ready forest plots for regression model outputs in Python.
Project description
forestplotx
forestplotx creates publication-style forest plots that combine a clean text table with a forest panel, with deterministic formatting for common regression outputs.
Features
- Publication-style table + forest composition
- Supports
binom,gamma,linear, andordinalmodel outputs - One or two outcomes per plot
- Deterministic internal layout presets for stable output
- Readable log-axis handling in both
decimalandpower10styles - Optional footer text for manuscript-style notes
- Visible column-header and x-axis label overrides
Note: For logit/log links, exponentiate=None applies model-based exponentiation with a warning; set exponentiate=False if your data is already on effect scale.
Displayed CI values in the table use bracket notation: [low,high].
API Reference
forest_plot()
fig, axes = fpx.forest_plot(
df, # DataFrame with model output
outcomes=None, # list[str], max 2; auto-detected if None
save=None, # File path to save (e.g. "plot.png")
model_type="binom", # "binom" | "gamma" | "linear" | "ordinal"
link=None, # Override default link function
exponentiate=None, # None=auto by link, True=force, False=disable
table_only=False, # Render table without forest panel
legend_labels=None, # list[str] override for legend entries
point_colors=None, # list[str], up to 2 hex codes for outcome markers
column_labels=None, # dict override for table column labels
x_label_override=None, # Override forest x-axis label
footer_text=None, # Italic footer (wrapped/capped internally)
tick_style="decimal", # "decimal" or "power10"
clip_outliers=False, # Opt-in clipping of extreme CI-driven axis outliers
clip_quantiles=(0.02, 0.98), # Retained for API compatibility
base_decimals=2, # Decimal places for effect / CI values
show=True, # Call plt.show(); set False for programmatic use
show_general_stats=True, # Show n / N / Freq columns
bold_override=None, # Manual bold control per predictor/outcome
)
Returns: (fig, axes) — matplotlib Figure and axes tuple. When show=False, the figure is returned without displaying, allowing further customization before calling plt.show() manually.
When exponentiate=None, auto exponentiation for log/logit links emits a warning so users can verify input scale.
Layout Behavior (v1)
forest_plot() uses fixed internal layout presets (including internal font size) for:
show_general_stats=True+ two outcomesshow_general_stats=True+ one outcomeshow_general_stats=False+ two outcomesshow_general_stats=False+ one outcome
This is intentional to keep output stable and publication-ready across common use cases.
base_decimals is capped at 3 internally to prevent table collisions in dense layouts.
For small row counts, figure height uses a tighter internal heuristic to reduce excessive whitespace.
Long footer text is wrapped and capped to 3 lines with ellipsis for overflow protection.
Within each layout case, deterministic pressure tiers are applied internally (standard, expanded, max) based on the final rendered string widths.
Predictor labels are truncated (with warning) when they exceed layout-specific caps:
show_general_stats=True+ two outcomes: 21 charsshow_general_stats=True+ one outcome: 24 charsshow_general_stats=False+ two outcomes: 26 charsshow_general_stats=False+ one outcome: 25 chars When general stats are shown, largen/Nvalues are compacted (e.g.,9.9k) to preserve column readability. Compaction activates only when counts reach>= 1,000and uses a shared unit across bothnandN(k,M,B,T) for consistent within-row formatting. Very large values beyond display range are capped as>999Twith a warning. Effect / CI display uses the same compact unit family (k,M,B,T) once values reach>= 1,000, followed by deterministic decimal trimming to keep tables readable. Rows are fully grayed only when all displayed outcomes are missing; if at least one outcome is valid, only the missing outcome triplet (effect,95% CI,p) is blanked and gray-marked.
Title Handling
forest_plot() intentionally does not include a title parameter in v1.
This is by design for publication workflows where figure titles/captions are managed in the manuscript rather than embedded inside the plot image.
If needed for slides or reports, add a title externally on the returned matplotlib figure object.
Exponentiation Safety
- Use
exponentiate=None(default) for model/link-based automatic handling. - Use
exponentiate=Falseif your input is already on effect scale (e.g., OR/Ratio, not log-coefficients). - Use
exponentiate=Trueonly when input is definitely on log scale and needs transformation. - Read warnings: they include auto-exponentiation context and column mapping (effect column +
CI_low/CI_highcombined into95% CI).
Axis Behavior
- Log-axis limits are data-driven after optional clipping; they are not forced symmetric around the reference value.
clip_outliers=Trueuses magnitude-based clipping centered on the median CI bounds, which works much better for small samples with one extreme interval.tick_style="decimal"uses readable decimal ticks:- dense near-reference ticks for moderate spans
1-2-5progression for wider spans- compact notation for very large tick labels when needed
tick_style="power10"keeps readable power-of-ten labels for very wide ratio ranges.
Label Overrides
Use column_labels to override visible table headers without changing the underlying model type:
fig, axes = fpx.forest_plot(
df,
model_type="gamma",
exponentiate=False,
column_labels={
"effect": "IRR",
"ci": "95% CI",
"p": "P",
"n": "Cases",
"N": "Total",
"Freq": "Share",
},
x_label_override="IRR",
)
Supported column_labels keys:
effectcipnNFreq
normalize_model_output()
clean_df, config = fpx.normalize_model_output(
df, model_type="binom", link=None, exponentiate=None
)
Standardizes columns, applies exponentiation policy, and returns axis metadata.
config includes exponentiated and renamed_columns for transparency.
Examples
Category grouping
df["category"] = ["Demographics", "Demographics", "Clinical", "Clinical"]
fig, axes = fpx.forest_plot(df, model_type="binom")
Dual outcomes
# DataFrame with two outcomes per predictor
fig, axes = fpx.forest_plot(
df_two_outcomes,
model_type="binom",
outcomes=["Mortality", "Readmission"],
legend_labels=["30-day mortality", "90-day readmission"],
)
Custom marker colors
fig, axes = fpx.forest_plot(
df_two_outcomes,
model_type="binom",
outcomes=["Mortality", "Readmission"],
point_colors=["#2C5F8A", "#D4763A"],
)
Linear model
fig, axes = fpx.forest_plot(df_linear, model_type="linear")
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file forestplotx-1.1.0.tar.gz.
File metadata
- Download URL: forestplotx-1.1.0.tar.gz
- Upload date:
- Size: 29.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4367d9c82a361e67d4110ca9b6e5b37eddbe7338f6e6ecc6fbfe295a33b7e74
|
|
| MD5 |
b80182d66ab9dec92bfe3cdc5f7356ca
|
|
| BLAKE2b-256 |
7987109aa7bc9706c155c3d3b36210c7f7f3b71d00d0cf20f963721dfa663077
|
File details
Details for the file forestplotx-1.1.0-py3-none-any.whl.
File metadata
- Download URL: forestplotx-1.1.0-py3-none-any.whl
- Upload date:
- Size: 20.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3608321cb03b36c61d6926b9e01cd4cac7341f2013874d08e41f5cf1d7b5dfb
|
|
| MD5 |
e98808b7e584b22e40b6b734bec1a833
|
|
| BLAKE2b-256 |
2557703a2946813e4397e105b876caa6963825da155337f2259009dea12778db
|