<!-- Source: https://docs.marimo.io/api/inputs/table/ -->

# Table

[Interactive marimo example](https://marimo.app/?embed=true&mode=edit&show-chrome=false#code/JYWwDg9gTgLgBCAhlUEBQixjgXgc1AOgEEsAKAd2ABMYALHAIhAFNrgBXERgSjTQACmMIQDGLADYS01FgDM4AfUVkeALjRwtcUJFj4UICHEQBnBOm1woLGBygA7QcLGTpshctUarMRACMJFlwLQg5gQj9AljJqRD8cCDk5YHFFUTpkRFEYFihTABo4MEQAc2AHeOAIBxwAFSgOFj4rGztHfiEsVykZeSUVdU1tI0IAN1M-UQBrMgBtKKCixZZxxAkmgF0W7Tb7J2du8V6PAe9hrSSUtIysnLzzPDmLqzgAb0YU-JhFStZGNRwRgAWVSmUkjCKjAkZh+fxYAKBAGVRBAYDBGABfAovKwfL6TX6If6AxgAKVAkKBMMJ8MRjAAEuswHkMdjcdp8cBvkSSUCAArEqnQ2G8hGkgBCLBYpgkAE8sTjXpzPtzacTxUCACJUUp0DFQmlwjX0lF0Rq5RUcrRcnl00nEBylSSIYVGsX04HIGAVK3Km2qu0m0kAaRYY19htF9qBXokNQR7P970D6r5jAA8qZRMg3dHg7HvRUWAAvP3+21pzWMJF+BxBBVRqv0hkcaimGrl5WV43p-l0OVSYCmPPN0kANUQDnEXdePY9pOBeTYwHoo971cFElYUFneNTG-pAGEbGx1wugRKoPEYJ2kxWDxfGAAlOVT88xxkQCjIah7lUEoeoZuI21L5umIaYBA0D-gGgFPnUED+KBIpjkCABiQQOLI+R3kqD7wZ+WrIFAg4fgWjD9sAEj+L697do+n4AKIoA45HpkyDgOHh1opoRFGOtQKHup+UqOL+sF8WqQFAmS75NjJjAADLhhUHZsfRc6MRRxERn+ClPgA6usMIzpp+78RxEBSMJ4HVphiAAB6zpsLx7B0QA)

## marimo.ui.table

```python
table(
    data: ListOrTuple[
        str | int | float | bool | MIME | None
    ]
    | ListOrTuple[dict[str, JSONType]]
    | dict[str, ListOrTuple[JSONType]]
    | IntoDataFrame,
    pagination: bool | None = None,
    selection: Literal[
        "single", "multi", "single-cell", "multi-cell"
    ]
    | None = "multi",
    initial_selection: list[int]
    | list[tuple[str, str]]
    | None = None,
    page_size: int | None = None,
    show_column_summaries: ShowColumnSummaries
    | None = None,
    show_data_types: bool = True,
    format_mapping: dict[str, str | Callable[..., Any]]
    | None = None,
    freeze_columns_left: Sequence[str] | None = None,
    freeze_columns_right: Sequence[str] | None = None,
    text_justify_columns: dict[
        str, Literal["left", "center", "right"]
    ]
    | None = None,
    wrapped_columns: list[str] | None = None,
    header_tooltip: dict[str, str] | None = None,
    show_download: bool = True,
    max_columns: MaxColumnsType = MAX_COLUMNS_NOT_PROVIDED,
    *,
    label: str = "",
    on_change: Callable[
        [
            list[JSONType]
            | dict[str, ListOrTuple[JSONType]]
            | IntoDataFrame
            | list[TableCell]
        ],
        None,
    ]
    | None = None,
    style_cell: Callable[[str, str, Any], dict[str, Any]]
    | None = None,
    hover_template: str
    | Callable[[str, str, Any], str]
    | None = None,
    max_height: int | None = None,
    _internal_column_charts_row_limit: int | None = None,
    _internal_summary_row_limit: int | None = None,
    _internal_total_rows: int
    | Literal["too_many"]
    | None = None,
    _internal_lazy: bool = False,
    _internal_preload: bool = False,
)
```

Bases: `UIElement[list[str] | list[int] | list[dict[str, Any]], list[JSONType] | IntoDataFrame | list[TableCell]]`

A table component with selectable rows.

Get the selected rows with `table.value`. The table data can be supplied as:

1. a list of dicts, with one dict for each row, keyed by column names;
2. a list of values, representing a table with a single column;
3. a Pandas dataframe; or
4. a Polars dataframe; or
5. an Ibis dataframe; or
6. a PyArrow table.

Examples:

Create a table from a list of dicts, one for each row:

```python
table = mo.ui.table(
    data=[
        {"first_name": "Michael", "last_name": "Scott"},
        {"first_name": "Dwight", "last_name": "Schrute"},
    ],
    label="Users",
)
```

Create a table from a single column of data:

```python
table = mo.ui.table(
    data=[
        {"first_name": "Michael", "last_name": "Scott"},
        {"first_name": "Dwight", "last_name": "Schrute"},
    ],
    label="Users",
)
```

Create a table from a dataframe:

```python
# df is a Pandas or Polars dataframe
table = mo.ui.table(
    data=df,
    # use pagination when your table has many rows
    pagination=True,
    label="Dataframe",
)
```

Create a table with format mapping:

```python
# format_mapping is a dict keyed by column names,
# with values as formatting functions or strings
def format_name(name):
    return name.upper()


table = mo.ui.table(
    data=[
        {"first_name": "Michael", "last_name": "Scott", "age": 45},
        {"first_name": "Dwight", "last_name": "Schrute", "age": 40},
    ],
    format_mapping={
        "first_name": format_name,  # Use callable to format first names
        "age": "{:.1f}".format,  # Use string format for age
    },
    label="Format Mapping",
)
```

Create a table with conditional cell formatting:

```python
import random


# rowId and columnName are strings.
def style_cell(_rowId, _columnName, value):
    # Apply inline styling to the visible individual cells.
    return {
        "backgroundColor": "lightcoral"
        if value < 4
        else "cornflowerblue",
        "color": "white",
        "fontStyle": "italic",
    }


table = mo.ui.table(
    data=[random.randint(0, 10) for x in range(200)],
    style_cell=style_cell,
)
table
```

Create a table with per-cell hover text (plain text only):

```python
import random


# rowId and columnName are strings.
def hover_cell(rowId, columnName, value):
    # Compute a short plain-text title for the visible individual cells.
    return f"Row {rowId} — {columnName}: {value}"


table = mo.ui.table(
    data=[random.randint(0, 10) for _ in range(200)],
    hover_template=hover_cell,
)
table
```

In each case, access the table data with `table.value`.

| ATTRIBUTE | DESCRIPTION |
| --- | --- |
| `[value](#marimo.ui.table.value)` | The selected rows, in the same format as the original data, or None if no selection. **TYPE:** `List[JSONType] \| IntoDataFrame` |
| `[data](#marimo.ui.table.data)` | The original table data. **TYPE:** `List[JSONType] \| IntoDataFrame` |

| PARAMETER | DESCRIPTION |
| --- | --- |
| `data` | Values can be primitives (`str`, `int`, `float`, `bool`, or `None`) or marimo elements: e.g. `mo.ui.button(...)`, `mo.md(...)`, `mo.as_html(...)`, etc. Data can be passed in many ways: - as dataframes: a pandas dataframe, a polars dataframe - as rows: a list of dicts, where each dict represents a row in the table - as columns: a dict keyed by column names, where the value of each entry is a list representing a column - as a single column: a list of values **TYPE:** `List[str \| int \| float \| bool \| MIME \| None] \| List[Dict[str, JSONType]] \| Dict[str, List[JSONType]] \| IntoDataFrame` |
| `pagination` | Whether to paginate; if False, all rows will be shown. Defaults to True when above 10 rows, False otherwise. **TYPE:** `bool` **DEFAULT:** `None` |
| `selection` | 'single' or 'multi' to enable row selection, 'single-cell' or 'multi-cell' to enable cell selection or None to disable. Defaults to "multi". **TYPE:** `Literal['single', 'multi', 'single-cell', 'multi-cell']` **DEFAULT:** `'multi'` |
| `initial_selection` | Indices of the rows you want selected by default. **TYPE:** `Union[List[int], List[tuple[str, str]]` **DEFAULT:** `None` |
| `page_size` | The number of rows to show per page. Defaults to 10. **TYPE:** `int` **DEFAULT:** `None` |
| `show_column_summaries` | Whether to show column summaries. Defaults to True when the table has less than 40 columns and at least 10 rows, False otherwise. If "stats", only show stats. If "chart", only show charts. **TYPE:** `bool \| Literal['stats', 'chart']` **DEFAULT:** `None` |
| `show_data_types` | Whether to show data types of columns in the table header. Defaults to True. **TYPE:** `bool` **DEFAULT:** `True` |
| `show_download` | Whether to show the download button. Defaults to True for dataframes, False otherwise. **TYPE:** `bool` **DEFAULT:** `True` |
| `format_mapping` | A mapping from column names to formatting strings or functions. **TYPE:** `Dict[str, str \| Callable[..., Any]]` **DEFAULT:** `None` |
| `freeze_columns_left` | List of column names to freeze on the left. **TYPE:** `Sequence[str]` **DEFAULT:** `None` |
| `freeze_columns_right` | List of column names to freeze on the right. **TYPE:** `Sequence[str]` **DEFAULT:** `None` |
| `text_justify_columns` | Dictionary of column names to text justification options: left, center, right. **TYPE:** `Dict[str, Literal['left', 'center', 'right']]` **DEFAULT:** `None` |
| `wrapped_columns` | List of column names to wrap. **TYPE:** `List[str]` **DEFAULT:** `None` |
| `header_tooltip` | Mapping from column names to tooltip text on the column header. **TYPE:** `Dict[str, str]` **DEFAULT:** `None` |
| `label` | Markdown label for the element. Defaults to "". **TYPE:** `str` **DEFAULT:** `''` |
| `on_change` | Optional callback to run when this element's value changes. **TYPE:** `Callable[[Union[List[JSONType], Dict[str, List[JSONType]], IntoDataFrame, List[TableCell]]], None]` **DEFAULT:** `None` |
| `style_cell` | A function that takes the row id, column name and value and returns a dictionary of CSS styles. **TYPE:** `Callable[[str, str, Any], Dict[str, Any]]` **DEFAULT:** `None` |
| `hover_template` | Either a string template applied at the row level, or a callable that computes plain-text hover titles for individual visible cells. When a callable is provided, values are computed per page in Python and passed to the frontend; native HTML `title` is used for display. Plain text only is supported. **TYPE:** `str \| Callable[[str, str, Any], str]` **DEFAULT:** `None` |
| `max_columns` | Maximum number of columns to display. Defaults to the configured default\_table\_max\_columns (50 by default). Set to None to show all columns. **TYPE:** `int` **DEFAULT:** `MAX_COLUMNS_NOT_PROVIDED` |
| `max_height` | Maximum height of the table body in pixels. When set, the table becomes vertically scrollable and the header will be made sticky in the UI to remain visible while scrolling. Defaults to None. **TYPE:** `int` **DEFAULT:** `None` |
| `label` | A descriptive name for the table. Defaults to "". **TYPE:** `str` **DEFAULT:** `''` |

### data `property`

```python
data: TableData
```

Get the original table data.

| RETURNS | DESCRIPTION |
| --- | --- |
| `TableData` | The original data passed to the table constructor, in its original format (list, dict, dataframe, etc.). **TYPE:** `TableData` |

### default\_page\_size `cached` `property`

```python
default_page_size: int
```

### text `property`

```python
text: str
```

A string of HTML representing this element.

### value `property` `writable`

```python
value: T
```

The element's current value.

### batch

```python
batch(**elements: UIElement[Any, Any]) -> batch
```

Convert an HTML object with templated text into a UI element.

This method lets you create custom UI elements that are represented
by arbitrary HTML.

> **Example**
>
> ```python3
> user_info = mo.md(
>     '''
>     - What's your name?: {name}
>     - When were you born?: {birthday}
>     '''
> ).batch(name=mo.ui.text(), birthday=mo.ui.date())
> ```
> In this example, `user_info` is a UI Element whose output is markdown
> and whose value is a dict with keys `'name'` and '`birthday`'
> (and values equal to the values of their corresponding elements).

| PARAMETER | DESCRIPTION |
| --- | --- |
| `elements` | the UI elements to interpolate into the HTML template. **TYPE:** `UIElement[Any, Any]` **DEFAULT:** `{}` |

### callout

```python
callout(
    kind: Literal[
        "neutral", "danger", "warn", "success", "info"
    ] = "neutral",
) -> Html
```

Create a callout containing this HTML element.

A callout wraps your HTML element in a raised box, emphasizing its
importance. You can style the callout for different situations with the
`kind` argument.

Examples:

```python3
mo.md("Hooray, you did it!").callout(kind="success")
```

```python3
mo.md("It's dangerous to go alone!").callout(kind="warn")
```

### center

```python
center() -> Html
```

Center an item.

> **Example**
>
> ```python3
> mo.md("# Hello, world").center()
> ```

| RETURNS | DESCRIPTION |
| --- | --- |
| `[Html](https://docs.marimo.io/api/html/#marimo.Html)` | An `Html` object. |

### form

```python
form(
    label: str = "",
    *,
    bordered: bool = True,
    loading: bool = False,
    submit_button_label: str = "Submit",
    submit_button_tooltip: str | None = None,
    submit_button_disabled: bool = False,
    clear_on_submit: bool = False,
    show_clear_button: bool = False,
    clear_button_label: str = "Clear",
    clear_button_tooltip: str | None = None,
    validate: Callable[[JSONType | None], str | None]
    | None = None,
    on_change: Callable[[T | None], None] | None = None,
) -> form[S, T]
```

Create a submittable form out of this `UIElement`.

Creates a form that gates submission of a `UIElement`'s value until a submit button is clicked.
The form's value is the value of the underlying element from the last submission.

Examples:

Convert any `UIElement` into a form:
```python
prompt = mo.ui.text_area().form()
```

Combine with `HTML.batch` to create a form made out of multiple `UIElements`:
```python
form = (
    mo.md(
        '''
    **Enter your prompt.**

    {prompt}

    **Choose a random seed.**

    {seed}
    '''
    )
    .batch(
        prompt=mo.ui.text_area(),
        seed=mo.ui.number(),
    )
    .form()
)
```

| PARAMETER | DESCRIPTION |
| --- | --- |
| `label` | A text label for the form. **TYPE:** `str` **DEFAULT:** `''` |
| `bordered` | Whether the form should have a border. **TYPE:** `bool` **DEFAULT:** `True` |
| `loading` | Whether the form should be in a loading state. **TYPE:** `bool` **DEFAULT:** `False` |
| `submit_button_label` | The label of the submit button. **TYPE:** `str` **DEFAULT:** `'Submit'` |
| `submit_button_tooltip` | The tooltip of the submit button. **TYPE:** `str \| None` **DEFAULT:** `None` |
| `submit_button_disabled` | Whether the submit button should be disabled. **TYPE:** `bool` **DEFAULT:** `False` |
| `clear_on_submit` | Whether the form should clear its contents after submitting. **TYPE:** `bool` **DEFAULT:** `False` |
| `show_clear_button` | Whether the form should show a clear button. **TYPE:** `bool` **DEFAULT:** `False` |
| `clear_button_label` | The label of the clear button. **TYPE:** `str` **DEFAULT:** `'Clear'` |
| `clear_button_tooltip` | The tooltip of the clear button. **TYPE:** `str \| None` **DEFAULT:** `None` |
| `validate` | A function that takes the form's value and returns an error message if invalid, or `None` if valid. **TYPE:** `Callable[[JSONType \| None], str \| None] \| None` **DEFAULT:** `None` |
| `on_change` | Optional callback to run when this element's value changes. Defaults to None. **TYPE:** `Callable[[T \| None], None] \| None` **DEFAULT:** `None` |

### from\_args `classmethod`

```python
from_args(
    data: dict[str, int],
    args: InitializationArgs[S, T],
    memo: dict[int, Any] | None = None,
    basis: UIElement[S, T] | None = None,
) -> UIElement[S, T]
```

### lazy `staticmethod`

```python
lazy(
    data: IntoLazyFrame,
    *,
    page_size: int | None = None,
    preload: bool = False,
) -> table
```

Create a table from a Polars LazyFrame.

This won't load the data into memory until requested by the user.
Once requested, only the first 10 rows will be loaded.

Pagination and selection are not supported for lazy tables.

| PARAMETER | DESCRIPTION |
| --- | --- |
| `data` | The data to display. **TYPE:** `IntoLazyFrame` |
| `page_size` | The number of rows to show per page. **TYPE:** `int` **DEFAULT:** `None` |
| `preload` | Whether to load the first page of data without user confirmation. Defaults to False. **TYPE:** `bool` **DEFAULT:** `False` |

### left

```python
left() -> Html
```

Left-justify.

> **Example**
>
> ```python3
> mo.md("# Hello, world").left()
> ```

| RETURNS | DESCRIPTION |
| --- | --- |
| `[Html](https://docs.marimo.io/api/html/#marimo.Html)` | An `Html` object. |

### right

```python
right() -> Html
```

Right-justify.

> **Example**
>
> ```python3
> mo.md("# Hello, world").right()
> ```

| RETURNS | DESCRIPTION |
| --- | --- |
| `[Html](https://docs.marimo.io/api/html/#marimo.Html)` | An `Html` object. |

### style

```python
style(
    style: dict[str, Any] | None = None, **kwargs: Any
) -> Html
```

Wrap an object in a styled container.

> **Example**
>
> ```python
> mo.md("...").style({"max-height": "300px", "overflow": "auto"})
> mo.md("...").style(max_height="300px", overflow="auto")
> ```

| PARAMETER | DESCRIPTION |
| --- | --- |
| `style` | an optional dict of CSS styles, keyed by property name **TYPE:** `dict[str, Any] \| None` **DEFAULT:** `None` |
| `**kwargs` | CSS styles as keyword arguments **TYPE:** `Any` **DEFAULT:** `{}` |