Graph Visualization

Visualize your Mesh graphs as beautiful Mermaid diagrams with automatic color-coding and clear flow representation.

Inspired by Pydantic Graph The visualization API design and mermaid.ink integration approach is inspired by Pydantic AI’s excellent graph visualization implementation. We’ve adapted the concept to fit Mesh’s unique node types and workflow patterns.

Table of Contents

  1. Overview
  2. Quick Start
  3. Node Type Colors
  4. Basic Usage
    1. Generate Mermaid Code
    2. Save as Image
  5. Visualization Patterns
    1. Sequential Workflow
    2. Conditional Branching
    3. Cyclic Graphs (Loops)
    4. Mixed Node Types
  6. Advanced Features
    1. Custom Direction
    2. Multiple Format Support
    3. Automatic END Node Detection
  7. API Reference
    1. StateGraph.mermaid_code()
    2. StateGraph.save_visualization()
  8. Examples
  9. Troubleshooting
    1. “HTTPError: 404 Not Found”
    2. “No module named ‘httpx’”
    3. Visualization is too wide/narrow
    4. Colors not showing correctly
  10. Best Practices
    1. 1. Use Descriptive Titles
    2. 2. Visualize Before Executing
    3. 3. Keep Graphs Reasonable Size
    4. 4. Version Control
    5. 5. Color Legend for Stakeholders
  11. Integration with Documentation
  12. See Also

Overview

Mesh provides built-in visualization capabilities that generate Mermaid flowchart diagrams from your graphs. These visualizations:

  • Automatically color-code different node types for easy identification
  • Show loop edges with iteration limits
  • Display termination points for cyclic graphs
  • Support multiple output formats: PNG, SVG, PDF
  • Use mermaid.ink API for image generation

Quick Start

Generate a visualization in two simple steps:

from mesh import StateGraph

# Build your graph
graph = StateGraph()
graph.add_node("process", my_function, node_type="tool")
graph.add_edge("process", "END")
graph.set_entry_point("process")

# Save visualization
output_path = graph.save_visualization(
    title="My Graph",
    format="png"
)
print(f"Saved to: {output_path}")

Node Type Colors

Each node type is automatically styled with a distinct color:

Node Type Color Shape Purpose
START Dark Gray Filled Circle Entry point
END Red Circle Termination point
Agent Red Rounded Rectangle Intelligent agent processing
LLM Blue Rounded Rectangle Direct LLM calls
Tool Green Rounded Rectangle Utility functions
Condition Yellow Diamond Decision/routing points
Loop Purple Rounded Rectangle Iteration nodes

This color-coding makes it easy to understand the role of each component at a glance.

Basic Usage

Generate Mermaid Code

Get the raw Mermaid flowchart code for your graph:

graph = StateGraph()
# ... build your graph

# Generate Mermaid code
mermaid_code = graph.mermaid_code(
    title="My Workflow",
    direction="TD"  # Top-Down or "LR" for Left-Right
)

print(mermaid_code)

Output:

---
title: My Workflow
---
flowchart TD
    process[tool: process]
    START(((START)))
    END(((END)))
    START --> process
    process --> END

    %% Node type styling
    classDef toolNode fill:#38a169,stroke:#2f855a,color:#fff
    ...

Save as Image

Save the visualization as a PNG, SVG, or PDF:

# Save with auto-generated filename
path = graph.save_visualization(
    title="my_graph",
    image_format="png"  # "png", "svg", or "pdf"
)

# Save to specific path
path = graph.save_visualization(
    output_path="/path/to/my_diagram.png",
    title="Custom Graph"
)

Default Location: mesh/visualizations/{title}_{timestamp}.{format}

Visualization Patterns

Sequential Workflow

Simple linear pipeline with no branching:

graph = StateGraph()

graph.add_node("step1", func1, node_type="tool")
graph.add_node("step2", func2, node_type="tool")
graph.add_node("step3", func3, node_type="tool")

graph.add_edge("step1", "step2")
graph.add_edge("step2", "step3")
graph.set_entry_point("step1")

graph.save_visualization(title="sequential_workflow")

Result: START → step1 → step2 → step3 → END

Conditional Branching

Decision points with multiple paths:

from mesh.nodes.condition import Condition

graph = StateGraph()

graph.add_node("analyzer", analyze_fn, node_type="tool")

conditions = [
    Condition("positive", lambda x: x["sentiment"] == "positive", "handler_a"),
    Condition("negative", lambda x: x["sentiment"] == "negative", "handler_b")
]
graph.add_node("router", conditions, node_type="condition")

graph.add_node("handler_a", handle_positive, node_type="tool")
graph.add_node("handler_b", handle_negative, node_type="tool")

graph.add_edge("analyzer", "router")
graph.add_edge("router", "handler_a")
graph.add_edge("router", "handler_b")

graph.set_entry_point("analyzer")
graph.save_visualization(title="conditional_branching")

Result:

  • Analyzer → Yellow Diamond (router) → [handler_a OR handler_b] → END
  • The condition node appears as a diamond shape

Cyclic Graphs (Loops)

Graphs with controlled loops show iteration limits and termination points:

graph = StateGraph()

graph.add_node("check", check_fn, node_type="tool")
graph.add_node("increment", increment_fn, node_type="tool")

graph.add_edge("check", "increment")
graph.add_edge(
    "increment",
    "check",
    is_loop_edge=True,
    max_iterations=20
)

graph.set_entry_point("check")
graph.save_visualization(title="loop_graph")

Result:

  • Loop edge labeled with “max: 20”
  • END node connects from check (the loop decision point)
  • Clear visual indication of where the loop exits

Mixed Node Types

Showcase all node type colors in one graph:

graph = StateGraph()

# Tool nodes (GREEN)
graph.add_node("preprocessor", preprocess, node_type="tool")

# Condition node (YELLOW)
graph.add_node("router", conditions, node_type="condition")

# LLM node (BLUE) - requires API key or mock
graph.add_node("llm", None, node_type="llm", model="gpt-4")

# Agent node (RED) - requires agent instance
graph.add_node("agent", my_agent, node_type="agent")

# Build edges...
graph.save_visualization(title="mixed_types")

Result: Each node type displays in its designated color

Advanced Features

Custom Direction

Control the flow direction of your diagram:

# Top-Down (default)
graph.mermaid_code(direction="TD")

# Left-Right
graph.mermaid_code(direction="LR")

Multiple Format Support

Save in different formats for different use cases:

# PNG for documentation
graph.save_visualization(title="docs_diagram", image_format="png")

# SVG for web/scaling
graph.save_visualization(title="web_diagram", image_format="svg")

# PDF for presentations
graph.save_visualization(title="presentation", image_format="pdf")

Automatic END Node Detection

Mesh automatically adds termination points for better visualization:

  1. Cyclic Graphs: END connects from loop decision nodes (where exit condition is evaluated)
  2. Linear Graphs: END connects from nodes with no forward edges
  3. Branching Graphs: END connects from all terminal branches

This ensures every visualization has a clear completion point.

API Reference

StateGraph.mermaid_code()

def mermaid_code(
    self,
    title: Optional[str] = None,
    direction: str = "TD"
) -> str:

Generate Mermaid flowchart code from the graph.

Parameters:

  • title (str, optional): Title displayed above the diagram
  • direction (str): Flowchart direction - “TD” (top-down) or “LR” (left-right)

Returns: String containing Mermaid flowchart code

StateGraph.save_visualization()

def save_visualization(
    self,
    output_path: Optional[str] = None,
    title: Optional[str] = None,
    image_format: str = "png",
    direction: str = "TD"
) -> str:

Generate and save a Mermaid diagram visualization.

Parameters:

  • output_path (str, optional): Path for output file. If None, auto-generates in mesh/visualizations/
  • title (str, optional): Title displayed above the diagram
  • image_format (str): Output format - “png”, “svg”, or “pdf”
  • direction (str): Flowchart direction - “TD” or “LR”

Returns: Path to saved image file (absolute path)

Raises:

  • httpx.HTTPError: If image generation via mermaid.ink fails
  • GraphValidationError: If graph structure is invalid

Examples

Complete working examples are available in examples/visualization_examples/:

  1. 01_cyclic_graph.py - Loop patterns with termination points
  2. 02_sequential_workflow.py - Linear pipeline visualization
  3. 03_conditional_branching.py - Decision points with diamond nodes
  4. 04_multi_agent_workflow.py - Multi-stage processing pipeline
  5. 05_mixed_node_types.py - Color palette showcase

Run any example:

python examples/visualization_examples/05_mixed_node_types.py

Each example:

  • Prints the Mermaid code
  • Saves a PNG to mesh/visualizations/
  • Explains the graph pattern

Troubleshooting

“HTTPError: 404 Not Found”

Cause: Mermaid.ink API issue or invalid Mermaid syntax

Solution:

  1. Check the generated Mermaid code with graph.mermaid_code()
  2. Verify syntax at Mermaid Live Editor
  3. Check network connectivity to mermaid.ink

“No module named ‘httpx’”

Cause: Missing httpx dependency

Solution:

pip install httpx

(httpx is included in Mesh’s base dependencies)

Visualization is too wide/narrow

Solution: Use different direction:

# Try left-right instead of top-down
graph.save_visualization(direction="LR")

Colors not showing correctly

Cause: Mermaid.ink may not support all styling

Solution:

  • Use PNG or SVG format (PDF has limited color support)
  • Verify Mermaid code manually with graph.mermaid_code()

Best Practices

1. Use Descriptive Titles

# Good
graph.save_visualization(title="user_registration_flow")

# Avoid
graph.save_visualization(title="graph1")

2. Visualize Before Executing

Generate visualizations during development to catch structural issues:

# Visualize first to verify structure
graph.save_visualization(title="dev_check")

# Then execute
compiled = graph.compile()
executor.execute(input, context)

3. Keep Graphs Reasonable Size

For graphs with 15+ nodes, consider:

  • Using left-right direction: direction="LR"
  • Breaking into sub-graphs
  • Focusing visualizations on specific sections

4. Version Control

Add visualizations to documentation but gitignore the output directory:

# .gitignore
mesh/visualizations/*.png
mesh/visualizations/*.svg
mesh/visualizations/*.pdf

Keep only reference diagrams in docs.

5. Color Legend for Stakeholders

When sharing visualizations, include the color legend:

# Graph Legend
- 🟢 GREEN: Data processing tools
- 🔵 BLUE: LLM-powered nodes
- 🔴 RED: Autonomous agents
- 🟡 YELLOW: Decision points

Integration with Documentation

Use visualizations in your documentation:

# My Workflow Documentation

## Architecture

![Workflow Diagram](../mesh/visualizations/my_workflow.png)

The workflow processes data through three stages...

See Also

  • Graphs - Understanding graph structure
  • Nodes - Node types and configuration
  • Loops - Creating controlled cycles
  • Examples - More usage examples