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:
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:
Markdown editor¶
marimo automatically renders cells that only use mo.md in a markdown editor
that supports common hotkeys. You can switch between the Markdown and Python
editors by clicking the button in the top right:
Writing LaTeX. The markdown editor supports writing LaTeX. You should typically
use a raw string for markdown with LaTeX, which you can activate by checking the r
box in the bottom-right corner of the markdown editor.
Interpolating Python values. Interpolating Python values requires using an
f-string, which you can activate by checking the f box in the bottom-right
corner of the markdown editor.
Markdown extensions¶
Details¶
Create expandable details with additional context:
Admonitions¶
Highlight text using admonitions:
Emoji¶
Use :emoji: syntax to add emojis; for example, :rocket: creates 🚀.
Static files¶
marimo supports serving static files from a public/ folder located next to your notebook. This is useful for including images or other static assets in your notebook.
To use files from the public folder, create a public directory next to your notebook and reference files using the public/ path prefix:
For security reasons:
- Only files within the
publicdirectory can be accessed - Symlinks are not followed
- Path traversal attempts (e.g.,
../) are blocked
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:
Media¶
marimo comes with functions to display media, including images, audio, video, pdfs, and more. See the API docs for more info.
Inspecting objects¶
marimo has built-in formatters for many objects, but sometimes the default
representation isn't useful (e.g., <MyClass at 0x...>). In these cases, use
mo.inspect() to explore an object's attributes, methods,
and documentation as an output. See the API
docs for more details.
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:
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.
Cleaning up your thread¶
When the cell that spawned a mo.Thread is invalidated
(re-run, deleted, interrupted, or otherwise errored), the thread's
should_exit property will evaluate to True, at which point it is your
responsibility to clean up your thread. You can retrieve the current
mo.Thread with mo.current_thread.
Example.
Patching threads created by third-party code¶
If you need to forward outputs from threads spawned by third-party code, try
patching threading.Thread:
This however may leak threads, since the patched threads won't know to check the mo.Thread's
should_exit property.