Loading...
Loading...
ALWAYS use when: creating/editing marimo notebooks, working with any .py file containing @app.cell decorators, building reactive Python notebooks, doing exploratory data analysis in notebook form, converting Jupyter (.ipynb) to marimo, or when user mentions "marimo", "reactive notebook", or asks for an interactive Python notebook. Covers marimo CLI (edit, run, convert, export), UI components (mo.ui.*), layout functions, SQL integration, caching, state management, and wigglystuff widgets. If a task involves notebooks and Python, invoke this skill first.
npx skill4agent add pymc-labs/agent-skills marimo-notebooks.pylist.append()@app.cell
def _(data):
def compute_mean_with_new_col(df):
temp = df.copy()
temp["new_col"] = temp["x"] * 2
return temp.mean()
return (compute_mean_with_new_col(data),)@app.cell
def _(model1_data):
model1_transformed = model1_data.copy()
model1_transformed["new_col"] = model1_transformed["x"] * 2
return (model1_transformed,)import marimo
__generated_with = "0.10.0"
app = marimo.App(width="medium")
@app.cell
def _():
import marimo as mo
return (mo,)
@app.cell
def _(mo):
mo.md("# Hello")
return
if __name__ == "__main__":
app.run()@app.cellreturn (var1, var2,)def _(mo, df):def model_specification():# Create & Edit
marimo new # Create new notebook
marimo edit notebook.py # Open editor
marimo edit notebook.py --watch # Live reload on file changes
# Run as App
marimo run notebook.py # Run as app (code hidden by default)
marimo run notebook.py --include-code # Show code in app view
# Convert
marimo convert notebook.ipynb -o notebook.py # Jupyter to marimo
# Export
marimo export html notebook.py -o out.html # Static HTML
marimo export ipynb notebook.py -o out.ipynb # To Jupyter
# Validate
marimo check notebook.py # Lint and validate
marimo check notebook.py --fix # Auto-fix issuesmarimo runmo.show_code()mo.show_code()@app.cell
def model_definition(mo, pm, X, y):
with pm.Model() as model:
alpha = pm.Normal("alpha", mu=0, sigma=10)
beta = pm.Normal("beta", mu=0, sigma=10)
mu = alpha + beta * X
pm.Normal("y", mu=mu, sigma=1, observed=y)
# Show this cell's code alongside its output
mo.show_code(model, position="above")
return (model,)# WRONG - do not put mo.show_code() in return statement
return mo.show_code(result)
# RIGHT - call as statement, then return separately
mo.show_code(result, position="above")
return (result,)position="above"position="below"@app.cell
def _(mo):
mo.md(r"""
# Title
Interpolate Python: {slider}
**LaTeX**: $f(x) = e^x$
$$\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}$$
**Icons**: ::lucide:rocket:: or ::mdi:home::
""")
returnr"""..."""f"Value: {slider}"f"Plot: {mo.as_html(fig)}"slider = mo.ui.slider(0, 100, value=50, label="Value")
number = mo.ui.number(0, 100, value=50)
text = mo.ui.text(value="", placeholder="Enter text")
checkbox = mo.ui.checkbox(value=False, label="Enable")
dropdown = mo.ui.dropdown(["a", "b", "c"], value="a")
radio = mo.ui.radio(["option1", "option2"], value="option1")
multiselect = mo.ui.multiselect(["a", "b", "c"])button = mo.ui.button(label="Click")
run_button = mo.ui.run_button(label="Run") # For triggering computationtable = mo.ui.table(df) # Interactive table with selection
dataframe = mo.ui.dataframe(df) # Editable dataframe
data_explorer = mo.ui.data_explorer(df) # No-code exploration# Forms (require submit button)
form = mo.ui.text().form()
# Batch in markdown
form = mo.md("""
**Name**: {name}
**Age**: {age}
""").batch(
name=mo.ui.text(),
age=mo.ui.number(0, 120)
).form()# Stacking
mo.hstack([el1, el2, el3], justify="center", gap=2)
mo.vstack([el1, el2, el3], align="start", gap=1)
# Containers
mo.accordion({"Section 1": content1, "Section 2": content2})
mo.tabs({"Tab 1": content1, "Tab 2": content2})
mo.callout(content, kind="info") # info, warn, success, danger, neutral
mo.sidebar([nav_content])
# Display
mo.tree({"a": {"b": 1}}) # Tree view
mo.stat(value="42", label="Users", caption="+5%")
mo.lazy(expensive_component) # Defer until visiblemo.output.replace(new_content) # Replace cell output
mo.output.append(additional) # Append to output
mo.output.clear() # Clear output
with mo.redirect_stdout():
print("This goes to cell output")# Progress bar
for item in mo.status.progress_bar(items, title="Processing"):
process(item)
# Spinner
with mo.status.spinner(title="Loading..."):
load_data()# Stop execution conditionally
mo.stop(condition, mo.md("*Message when stopped*"))
# Example: require button click
run_button = mo.ui.run_button()
mo.stop(not run_button.value, mo.md("Click Run to execute"))
expensive_computation()# In-memory cache (session only)
@mo.cache
def expensive_function(x, y):
return compute(x, y)
# Persistent cache (survives restarts)
@mo.persistent_cache(name="embeddings")
def compute_embeddings(text):
return model.encode(text)mo.state()@app.cell
def _(mo):
get_count, set_count = mo.state(0)
return get_count, set_count
@app.cell
def _(mo, get_count, set_count):
mo.ui.button(
label=f"Count: {get_count()}",
on_click=lambda _: set_count(lambda n: n + 1)
)
return# Altair with selection
chart = alt.Chart(df).mark_point().encode(x="x", y="y")
selection = mo.ui.altair_chart(chart, chart_selection="point")
selected_data = selection.value # DataFrame of selected points
# Plotly
fig = px.scatter(df, x="x", y="y")
interactive = mo.ui.plotly(fig)
interactive.value # Selected points
# Matplotlib interactive
fig, ax = plt.subplots()
ax.plot(x, y)
mo.mpl.interactive(fig)from wigglystuff import Slider2D, Paint, SortableList, Matrix, CellTour
import marimo as mo
slider2d = mo.ui.anywidget(Slider2D())
slider2d.x, slider2d.y
paint = mo.ui.anywidget(Paint(width=400, height=300))
paint.to_pil()
tour = mo.ui.anywidget(CellTour(
steps=[
{"cell_name": "intro", "title": "Welcome", "description": "..."},
{"cell_name": "model", "title": "Model", "description": "..."},
],
auto_start=False
))model1_sigmamodel2_sigmamo.lazy()@mo.cache@mo.persistent_cachemarimo check notebook.pyprint(mo.md()mo.stat()mo.callout()marimo check notebook.pymo.md(f"**Label:** {value}")mo.stat(value=f"{x}", label="Label")mo.callout(content, kind="info")lambda v, i=i: ...lambda v: ... imo.ui.array()mo.ui.dictionary()mo.ui.batch()x: "SomeType"plt.tight_layout()dotenv.load_dotenv(dotenv.find_dotenv(usecwd=True))