Skip to content

๐Ÿ“ย ย Diagrams

Submitted by Arnaud Miribel

Summary

Render mingrammer/diagrams architecture diagrams in Streamlit, plus a built-in Streamlit node.

Functions

st_diagram

Render a diagrams architecture diagram in Streamlit.

Parameters:

Name Type Description Default
diagram Diagram

A diagrams.Diagram context-manager object (use show=False when creating it).

required
format Literal['svg', 'png']

Output format. "svg" (default) renders crisp vector graphics via a custom component. "png" uses st.image.

'svg'
width int | Literal['stretch', 'content']

Image width. "stretch" (default) fills the container, "content" uses the intrinsic size, or pass an int for a fixed pixel width.

'stretch'
caption str | None

Optional caption displayed below the diagram.

None
Source code in src/streamlit_extras/diagrams/__init__.py
@extra
def st_diagram(
    diagram: DiagramType,
    *,
    format: Literal["svg", "png"] = "svg",
    width: int | Literal["stretch", "content"] = "stretch",
    caption: str | None = None,
) -> None:
    """Render a ``diagrams`` architecture diagram in Streamlit.

    Args:
        diagram: A ``diagrams.Diagram`` context-manager object
            (use ``show=False`` when creating it).
        format: Output format. ``"svg"`` (default) renders crisp vector
            graphics via a custom component. ``"png"`` uses ``st.image``.
        width: Image width. ``"stretch"`` (default) fills the container,
            ``"content"`` uses the intrinsic size, or pass an ``int`` for
            a fixed pixel width.
        caption: Optional caption displayed below the diagram.
    """
    dot = diagram.dot
    dark = _is_dark_mode()

    saved_graph = dict(dot.graph_attr)
    saved_node = dict(dot.node_attr)
    saved_edge = dict(dot.edge_attr)
    saved_body = list(dot.body)

    dot.graph_attr["bgcolor"] = "transparent"

    if dark:
        for key in ("fontcolor",):
            if key in dot.graph_attr:
                dot.graph_attr[key] = _swap_colors(dot.graph_attr[key])
            if key in dot.node_attr:
                dot.node_attr[key] = _swap_colors(dot.node_attr[key])
        for key in ("color", "fontcolor"):
            if key in dot.edge_attr:
                dot.edge_attr[key] = _swap_colors(dot.edge_attr[key])
        dot.body[:] = [_swap_colors(line) for line in dot.body]

    try:
        raw = dot.pipe(format=format)
    finally:
        dot.graph_attr.clear()
        dot.graph_attr.update(saved_graph)
        dot.node_attr.clear()
        dot.node_attr.update(saved_node)
        dot.edge_attr.clear()
        dot.edge_attr.update(saved_edge)
        dot.body[:] = saved_body

    if format == "png":
        from PIL import Image

        img = Image.open(BytesIO(raw))
        use_cw = width == "stretch"
        kw: dict[str, object] = {"caption": caption, "use_container_width": use_cw}
        if isinstance(width, int):
            kw["width"] = width
        st.image(img, **kw)  # type: ignore[arg-type]
        return

    svg_str = raw.decode("utf-8")
    svg_str = _inline_images(svg_str)

    component_width = width if isinstance(width, str) else "content"
    _DIAGRAM_COMPONENT(
        data={"svg": svg_str, "width": width, "caption": caption or ""},
        width=component_width,
    )

Import:

from streamlit_extras.diagrams import st_diagram # (1)!
  1. You should add this to the top of your .py file ๐Ÿ› 

Examples

example

def example() -> None:
    try:
        from diagrams import Diagram
        from diagrams.aws.compute import EC2
        from diagrams.aws.database import RDS
        from diagrams.aws.network import ELB

        with Diagram(
            "Streamlit App Architecture",
            show=False,
            direction="LR",
            graph_attr={"pad": "0.5", "labelloc": "t"},
        ) as diag:
            StreamlitNode("Frontend") >> ELB("Load Balancer") >> EC2("API Server") >> RDS("Database")

        st_diagram(diag, caption="Built with the diagrams library")
    except ImportError:
        st.warning(
            "This example requires the `diagrams` package and Graphviz. "
            "Install with `pip install diagrams` and [install Graphviz](https://graphviz.org/download/)."
        )