UI components (e.g. mo.ui.button) behave inconsistently when rendered in a marimo.ui.table, depending on whether it is stored within a Python dict/list or a Pandas DataFrame.
In a dict, the button is rendered as an interactive UI component, but when placed in a Pandas DataFrame, it is rendered as a string instead. This behavior is unexpected, as one would expect the button to be rendered consistently across both data structures:
I think it is down to how to_data is implemented in DefaultTableManager vs. PandasTableManager. In DefaultTableManager, to_data normalizes the data and returns it:
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "marimo",
# "pandas==2.2.3",
# ]
# ///
import marimo
__generated_with = "0.9.10"
app = marimo.App(width="medium")
@app.cell
def __():
import marimo as mo
import pandas as pd
return mo, pd
@app.cell
def __(mo):
mo.md(r"""How an `mo.ui.button` is rendered in an `mo.ui.table` varies depending on the data structure it is contained within.""")
return
@app.cell
def __(mo):
button = mo.ui.button(label='Click me')
return (button,)
@app.cell
def __(button):
data = {'Buttons': [button]}
return (data,)
@app.cell
def __(data, mo):
mo.md(f"""
## dict/list
If the button is in a regular dict/list, it is rendered as a UI component:
{mo.ui.table(data)}
""")
return
@app.cell
def __(button, pd):
df = pd.DataFrame({'Buttons': [button]})
return (df,)
@app.cell
def __(df, mo):
mo.md(f"""
## Pandas DataFrame
If the button is in a Pandas DataFrame, it is rendered as a string:
{mo.ui.table(df)}
""")
return
if __name__ == "__main__":
app.run()
Yea i think we can write a proper to_data, which can contain rich objects, instead of writing to_csv (which is limited to strings) for each dataframe implementation
Describe the bug
UI components (e.g.
mo.ui.button
) behave inconsistently when rendered in amarimo.ui.table
, depending on whether it is stored within a Python dict/list or a Pandas DataFrame.In a dict, the button is rendered as an interactive UI component, but when placed in a Pandas DataFrame, it is rendered as a string instead. This behavior is unexpected, as one would expect the button to be rendered consistently across both data structures:
I think it is down to how
to_data
is implemented inDefaultTableManager
vs.PandasTableManager
. InDefaultTableManager
,to_data
normalizes the data and returns it:https://github.com/marimo-team/marimo/blob/257238bec616f4548f92508ccb510e9640faa958/marimo/_plugins/ui/_impl/tables/default_table.py#L76-L83
In
PandasTableManager
,to_data
is not defined, soto_data
fromTableManager
is used, which turns it into CSV:https://github.com/marimo-team/marimo/blob/257238bec616f4548f92508ccb510e9640faa958/marimo/_plugins/ui/_impl/tables/table_manager.py#L40-L50
Environment
{ "marimo": "0.9.10", "OS": "Darwin", "OS Version": "22.3.0", "Processor": "arm", "Python Version": "3.12.6", "Binaries": { "Browser": "129.0.6668.101", "Node": "v22.9.0" }, "Dependencies": { "click": "8.1.7", "importlib-resources": "missing", "jedi": "0.19.1", "markdown": "3.7", "pygments": "2.18.0", "pymdown-extensions": "10.10.1", "ruff": "0.6.7", "starlette": "0.39.0", "tomlkit": "0.13.2", "typing-extensions": "4.12.2", "uvicorn": "0.30.6", "websockets": "12.0" }, "Optional Dependencies": {} }
Code to reproduce