GT.fmt_chem()

Format chemical formulas.

Usage

Source

GT.fmt_chem(
    columns=None,
    rows=None,
)

With fmt_chem() you can format chemical formulas and reactions in the table body. Often the input text will be in a common form representing single compounds (like "C2H4O" for acetaldehyde) but chemical reactions can also be used (e.g., "2 CH3OH -> CH3OCH3 + H2O"). So long as the text within the targeted cells conforms to the specialized chemistry notation, the appropriate conversions will occur. Details on chemistry notation can be found in the section entitled How to use chemistry notation.

Parameters

columns: SelectExpr = None

The columns to target. Can either be a single column name or a series of column names provided in a list.

rows: int | list[int] | None = None
In conjunction with columns=, we can specify which of their rows should undergo formatting. The default is all rows, resulting in all rows in targeted columns being formatted. Alternatively, we can supply a list of row indices.

Returns

GT
The GT object is returned. This is the same object that the method is called on so that we can facilitate method chaining.

How To Use Chemistry Notation

The chemistry notation involves a shorthand for writing chemical formulas and reactions. It should feel familiar in its basic usage and the more advanced typesetting tries to limit the amount of syntax needed. Here are examples of the supported features:

  • "CH3O2" and "(NH4)2S" will render with subscripted numerals

  • Charges can be expressed with terminating "+" or "-", as in "H+" and "[AgCl2]-"; numbered charges use: "CrO4^2-", "Fe^n+", "Y^99+", or "Y^{99+}"

  • Stoichiometric values can prepend formulas: "2H2O2", "2 H2O2", "0.5 H2O", "1/2 H2O", "(1/2) H2O"

  • Certain standalone lowercase letters are automatically italicized: "NO_x" and "x Na(NH4)HPO4" will have italic x characters; you can always italicize with "*" (as in "*n* H2O")

  • Chemical isotopes can be rendered as: "^{227}_{90}Th" or "^227_90Th"; nuclides are similar: "^{0}_{-1}n^{-}", "^0_-1n-"

  • Chemical reactions can use "+" signs and a variety of reaction arrows: "->", "<-", "<->", "<-->", "<=>", "<=>>", "<<=>"

  • Center dots (for addition compounds) use a single "." or "*" surrounded by spaces: "KCr(SO4)2 . 12 H2O" or "KCr(SO4)2 * 12 H2O"

  • Single and double bonds between adjacent characters use "-" or "=": "C6H5-CHO", "CH3CH=CH2"

  • Greek letters can be inserted using colon notation: ":delta: ^13C"

Examples

Let’s use the reactions dataset and create a table of gas-phase reaction rate constants for selected terminal alkenes. The cmpd_formula column contains chemical formulas and fmt_chem() will render them with properly subscripted numerals. Notice that the column labels for O₃ and NO₃ use the {%...%} chemistry notation within cols_label().

import polars as pl
import polars.selectors as cs
from great_tables import GT, data

reactions_mini = (
    data.pl.reactions
    .filter(
        (pl.col("cmpd_type") == "terminal monoalkene")
        & pl.col("cmpd_name").str.starts_with("1-")
    )
    .select("cmpd_name", "cmpd_formula", cs.ends_with("k298"))
)

(
    GT(reactions_mini)
    .tab_header(title="Gas-Phase Reactions of Selected Terminal Alkenes")
    .tab_spanner(
        label="Reaction Rate Constant at 298 K",
        columns=cs.ends_with("k298"),
    )
    .fmt_chem(columns="cmpd_formula")
    .fmt_scientific(columns=cs.ends_with("k298"))
    .sub_missing()
    .cols_label(
        cmpd_name="Alkene",
        cmpd_formula="Formula",
        OH_k298="OH",
        O3_k298="{{%O3%}}",
        NO3_k298="{{%NO3%}}",
        Cl_k298="Cl",
    )
    .opt_align_table_header(align="left")
)
Gas-Phase Reactions of Selected Terminal Alkenes
Alkene Formula Reaction Rate Constant at 298 K
OH O3 NO3 Cl
1-butene C4H8 3.10 × 10−11 1.00 × 10−17 1.30 × 10−14 3.00 × 10−10
1-pentene C5H10 3.22 × 10−11 1.06 × 10−17 1.50 × 10−14 4.20 × 10−10
1-hexene C6H12 3.70 × 10−11 1.15 × 10−17 1.80 × 10−14 4.00 × 10−10
1-heptene C7H14 3.88 × 10−11 1.16 × 10−17 2.00 × 10−14 4.40 × 10−10
1-octene C8H16 3.44 × 10−11 1.01 × 10−17 2.50 × 10−14 5.50 × 10−10
1-nonene C9H18 4.32 × 10−11 9.90 × 10−18 — 5.90 × 10−10
1-decene C10H20 4.61 × 10−11 1.11 × 10−17 2.60 × 10−14 —
1-undecene C11H22 4.79 × 10−11 1.03 × 10−17 — —
1-dodecene C12H24 5.03 × 10−11 1.03 × 10−17 2.80 × 10−14 —
1-tridecene C13H26 5.09 × 10−11 9.60 × 10−18 — —
1-tetradecene C14H28 4.96 × 10−11 9.70 × 10−18 2.80 × 10−14 —

The photolysis dataset contains photolysis pathways where both the cmpd_formula and products columns hold chemistry notation. We can format both columns with fmt_chem() and use cols_merge() to combine the compound name with its formatted formula.

photolysis_mini = (
    data.pl.photolysis
    .filter(pl.col("cmpd_name").is_in([
        "hydrogen peroxide", "nitrous acid",
        "nitric acid", "acetaldehyde",
        "methyl peroxide", "methyl nitrate",
        "ethyl nitrate", "isopropyl nitrate",
    ]))
    .select(pl.exclude("l", "m", "n", "quantum_yield", "type"))
)

(
    GT(photolysis_mini)
    .tab_header(title="Photolysis Pathways of Selected VOCs")
    .fmt_chem(columns=["cmpd_formula", "products"])
    .cols_merge(
        columns=["cmpd_name", "cmpd_formula"],
        pattern="{0}, {1}",
    )
    .cols_label(cmpd_name="Compound", products="Products")
    .cols_hide(columns=["wavelength_nm", "sigma_298_cm2"])
    .opt_align_table_header(align="left")
)
Photolysis Pathways of Selected VOCs
Compound Products
hydrogen peroxide, H2O2 → OH + OH
nitrous acid, HONO → OH + NO
nitric acid, HNO3 → OH + NO2
acetaldehyde, CH3CHO → HCO + CH3
methyl peroxide, CH3OOH → CH3O + OH
methyl nitrate, CH3ONO2 → CH3O + NO2
ethyl nitrate, C2H5ONO2 → C2H5O + NO2
isopropyl nitrate, i-C3H7ONO2 → i-C3H7O + NO2

The nuclides dataset contains isotope data with nuclide notation (e.g., "^{12}_{6}C") that fmt_chem() renders with properly overstruck mass and atomic numbers. Here we show isotopes of hydrogen and carbon.

from great_tables import md

nuclides_mini = (
    data.pl.nuclides
    .filter(pl.col("element").is_in(["H", "C"]))
    .with_columns(pl.col("nuclide").str.replace(r"[0-9]+$", ""))
    .select("nuclide", "atomic_mass", "half_life", "decay_1", "is_stable")
)

stable = (
    nuclides_mini.with_row_index()
    .filter(pl.col("is_stable") == "TRUE")["index"].to_list()
)
unstable = (
    nuclides_mini.with_row_index()
    .filter(pl.col("is_stable") == "FALSE")["index"].to_list()
)

(
    GT(nuclides_mini, rowname_col="nuclide")
    .tab_header(title="Isotopes of Hydrogen and Carbon")
    .tab_stubhead(label="Isotope")
    .fmt_chem(columns="nuclide")
    .fmt_scientific(columns="half_life")
    .fmt_number(columns="atomic_mass", decimals=4, scale_by=1 / 1e6)
    .sub_missing(
        columns="half_life", rows=stable, missing_text=md("**STABLE**")
    )
    .sub_missing(columns="half_life", rows=unstable)
    .sub_missing(columns="decay_1")
    .cols_hide(columns="is_stable")
    .cols_align(align="center", columns="decay_1")
    .cols_label(decay_1="Decay Mode")
    .opt_align_table_header(align="left")
    .opt_vertical_padding(scale=0.5)
)
Isotopes of Hydrogen and Carbon
Isotope atomic_mass half_life Decay Mode
1
1
H
1.0078 STABLE —
2
1
H
2.0141 STABLE —
3
1
H
3.0160 3.89 × 108 B-
4
1
H
4.0264 — N
5
1
H
5.0353 8.61 × 10−23 2N
6
1
H
6.0450 2.94 × 10−22 —
7
1
H
7.0527 5.07 × 10−21 —
8
6
C
8.0376 3.51 × 10−21 2P
9
6
C
9.0310 1.26 × 10−1 EC+B+
10
6
C
10.0169 1.93 × 101 EC+B+
11
6
C
11.0114 1.22 × 103 EC+B+
12
6
C
12.0000 STABLE —
13
6
C
13.0034 STABLE —
14
6
C
14.0032 1.80 × 1011 B-
15
6
C
15.0106 2.45 B-
16
6
C
16.0147 7.47 × 10−1 B-
17
6
C
17.0226 1.93 × 10−1 B-
18
6
C
18.0268 9.20 × 10−2 B-
19
6
C
19.0348 4.63 × 10−2 B-
20
6
C
20.0403 1.63 × 10−2 B-
22
6
C
22.0576 6.10 × 10−3 B-