Skip to content

๐Ÿงฎย ย Great Tables

Submitted by Lukas Masuch

Summary

Render Great Tables objects in Streamlit. Great Tables allows you to create wonderful-looking display tables in Python.

The table automatically adapts to Streamlit's theme (light/dark) and updates live when the user switches themes.

Functions

great_tables

Render a Great Tables object in Streamlit.

Parameters:

Name Type Description Default
table GT

A Great Tables object.

required
width int | Literal['stretch', 'content']

The width of the table. One of: - "stretch" (default): Stretch the table to the width of the container. - "content": Use the table's natural width based on content. - int: A fixed width in pixels.

'stretch'
theme Literal['streamlit'] | None

The theme to apply to the table. One of: - "streamlit" (default): Apply Streamlit's theme colors (text, background, borders) to the table. The table automatically adapts when the user switches between light and dark themes. - None: Preserve Great Tables' original styling.

'streamlit'
Source code in src/streamlit_extras/great_tables/__init__.py
@extra
def great_tables(
    table: GT,
    width: int | Literal["stretch", "content"] = "stretch",
    *,
    theme: Literal["streamlit"] | None = "streamlit",
) -> None:
    """
    Render a Great Tables object in Streamlit.

    Args:
        table: A Great Tables object.
        width: The width of the table. One of:
            - `"stretch"` (default): Stretch the table to the width of the container.
            - `"content"`: Use the table's natural width based on content.
            - `int`: A fixed width in pixels.
        theme: The theme to apply to the table. One of:
            - `"streamlit"` (default): Apply Streamlit's theme colors (text, background,
              borders) to the table. The table automatically adapts when the user
              switches between light and dark themes.
            - `None`: Preserve Great Tables' original styling.
    """
    # Apply width settings via tab_options for proper table sizing
    if width == "stretch":
        table = table.tab_options(container_width="100%", table_width="100%")
    elif isinstance(width, int):
        table = table.tab_options(container_width=f"{width}px", table_width=f"{width}px")
    # "content" - don't modify, use GT's default sizing

    html = table.as_raw_html()

    if theme == "streamlit":
        # Use CCv2 component with live theme support
        component_width: Literal["stretch", "content"] = "stretch" if width == "stretch" else "content"
        _GREAT_TABLES_COMPONENT(
            data={"html": html, "width": width},
            width=component_width,
        )
    else:
        # Fall back to st.html for users who want original GT styling
        st.html(html)

Import:

from streamlit_extras.great_tables import great_tables # (1)!
  1. You should add this to the top of your .py file ๐Ÿ› 

Examples

example

def example() -> None:
    """Basic example with S&P 500 data."""
    try:
        from great_tables import GT
        from great_tables.data import sp500

        # Define the start and end dates for the data range
        start_date = "2010-06-07"
        end_date = "2010-06-14"

        # Filter sp500 using Pandas to dates between `start_date` and `end_date`
        sp500_mini = sp500[(sp500["date"] >= start_date) & (sp500["date"] <= end_date)]

        # Create a display table based on the `sp500_mini` table data
        table = (
            GT(sp500_mini)
            .tab_header(title="S&P 500", subtitle=f"{start_date} to {end_date}")
            .fmt_currency(columns=["open", "high", "low", "close"])
            .fmt_date(columns="date", date_style="wd_m_day_year")
            .fmt_number(columns="volume", compact=True)
            .cols_hide(columns="adj_close")
        )

        great_tables(table, width="stretch")
    except ImportError:
        st.warning("This example requires the `great_tables` package. Install it with `pip install great-tables`.")

example_column_spanners

def example_column_spanners() -> None:
    """Example with column spanners and HTML labels."""
    try:
        from great_tables import GT, html
        from great_tables.data import airquality

        # Use first 10 rows of air quality data
        airquality_mini = airquality.head(10).assign(Year=1973)

        table = (
            GT(airquality_mini)
            .tab_header(
                title="New York Air Quality Measurements",
                subtitle="Daily measurements in New York City (May 1-10, 1973)",
            )
            .tab_spanner(label="Time", columns=["Year", "Month", "Day"])
            .tab_spanner(label="Measurement", columns=["Ozone", "Solar_R", "Wind", "Temp"])
            .cols_move_to_start(columns=["Year", "Month", "Day"])
            .cols_label(
                Ozone=html("Ozone,<br>ppbV"),
                Solar_R=html("Solar R.,<br>cal/m<sup>2</sup>"),
                Wind=html("Wind,<br>mph"),
                Temp=html("Temp,<br>&deg;F"),
            )
        )

        great_tables(table, width="stretch")
    except ImportError:
        st.warning("This example requires the `great_tables` package. Install it with `pip install great-tables`.")

example_data_coloring

def example_data_coloring() -> None:
    """Example with data coloring (heat map style)."""
    try:
        from great_tables import GT, html
        from great_tables.data import sza

        # Filter and pivot the solar zenith angle data
        # Filter to latitude 20 and morning hours, then pivot to wide format
        sza_filtered = sza[(sza["latitude"] == "20") & (sza["tst"] <= "1200")].dropna()

        # Pivot the data: months as rows, times as columns
        sza_pivot = sza_filtered.pivot(index="month", columns="tst", values="sza")
        sza_pivot = sza_pivot.reset_index()

        table = (
            GT(sza_pivot, rowname_col="month")
            .data_color(
                domain=[90, 0],
                palette=["rebeccapurple", "white", "orange"],
                na_color="white",
            )
            .tab_header(
                title="Solar Zenith Angles from 05:30 to 12:00",
                subtitle=html("Average monthly values at latitude of 20&deg;N."),
            )
            .sub_missing(missing_text="")
        )

        great_tables(table, width="stretch")
    except ImportError:
        st.warning("This example requires the `great_tables` package. Install it with `pip install great-tables`.")

example_row_groups

def example_row_groups() -> None:
    """Example with row grouping by region."""
    try:
        from great_tables import GT
        from great_tables.data import countrypops

        # Define Oceania regions and their countries
        oceania = {
            "Australasia": ["AU", "NZ"],
            "Melanesia": ["NC", "PG", "SB", "VU"],
            "Micronesia": ["FM", "GU", "KI", "MH", "MP", "NR", "PW"],
            "Polynesia": ["PF", "WS", "TO", "TV"],
        }

        # Create mapping from country code to region
        country_to_region = {country: region for region, countries in oceania.items() for country in countries}

        # Filter to Oceania countries and years 2000, 2010, 2020
        oceania_codes = list(country_to_region.keys())
        years = [2000, 2010, 2020]

        filtered = countrypops[
            (countrypops["country_code_2"].isin(oceania_codes)) & (countrypops["year"].isin(years))
        ].copy()

        # Add region column
        filtered["region"] = filtered["country_code_2"].map(country_to_region)

        # Pivot to wide format (years as columns)
        wide_pops = filtered.pivot(index=["country_name", "region"], columns="year", values="population").reset_index()

        # Rename columns to strings for GT
        wide_pops.columns = [str(c) for c in wide_pops.columns]

        # Sort by 2020 population descending
        wide_pops = wide_pops.sort_values("2020", ascending=False)

        table = (
            GT(wide_pops)
            .tab_header(title="Populations of Oceania's Countries", subtitle="Years 2000, 2010, and 2020")
            .tab_stub(rowname_col="country_name", groupname_col="region")
            .cols_hide(columns="region")
            .fmt_integer(columns=["2000", "2010", "2020"])
        )

        great_tables(table, width="stretch")
    except ImportError:
        st.warning("This example requires the `great_tables` package. Install it with `pip install great-tables`.")