Skip to content

Visualizing outputs

The last expression of a cell is its visual output, rendered above the cell. Outputs are included in the "app" or read-only view of the notebook. marimo comes out of the box a number of elements to help you make rich outputs, documented in the API reference.

Markdown

Markdown is written with the marimo library function mo.md. Writing markdown programmatically lets you make dynamic markdown: interpolate Python values into markdown strings, conditionally render your markdown, and embed markdown in other objects.

Here's a simple hello world example:

import marimo as mo
name = mo.ui.text(placeholder="Your name here")
mo.md(
  f"""
  Hi! What's your name?

  {name}
  """
)
mo.md(
  f"""
  Hello, {name.value}!
  """
)

Notice that marimo knows how to render marimo objects in markdown: you can just embed them in mo.md() using an f-string, and marimo will figure out how to display them!

For other objects, like matplotlib plots, wrap them in mo.as_html() to tap into marimo's media viewer:

mo.md(
  f"""
  Here's a plot!

  {mo.as_html(figure)}
  """
)

Markdown editor

marimo automatically renders cells that only use mo.md(""), without an f-string, in a markdown editor that supports common hotkeys.

Because the Markdown editor doesn't support f-strings, you'll need to use mo.md directly to interpolate Python values into your Markdown. You can switch between the Markdown and Python editors by clicking the button in the top right.

marimo is pure Python, even when you're using markdown.

Layout

The marimo library also comes with elements for laying out outputs, including mo.hstack, mo.vstack, mo.accordion, mo.ui.tabs, mo.sidebar, mo.nav_menu, mo.ui.table, and many more.

Progress bars

Use mo.status.progress_bar and mo.status.spinner to create progress indicators:

# mo.status.progress_bar is similar to TQDM
for i in mo.status.progress_bar(range(10)):
  print(i)

Media

marimo comes with functions to display media, including images, audio, video, pdfs, and more. See the API docs for more info.

Imperatively adding outputs

While a cell's output is its last expression, it can at times be helpful to imperatively add to the output area while a cell is running. marimo provides utility functions like mo.output.append for accomplishing this; see the API docs for more information.

Console Outputs

Console outputs, such as print statements, show up below a cell in the console output area; they are not included in the output area or app view by default.

To include console outputs in the cell output area, use mo.redirect_stdout or mo.redirect_stderr:

with mo.redirect_stdout():
  print("Hello, world!")

marimo also includes utility functions for capturing standard out and standard error without redirecting them. See the API docs for more.

Threading

To create a thread that can reliably communicate outputs to the frontend, use mo.Thread, which has exactly the same API as as threading.Thread.

If you need to forward outputs from threads spawned by third-party code, try patching threading.Thread:

import threading
import marimo as mo

threading.Thread = mo.Thread