Skip to main content
A minimal guide to rendering your current knowledge graph to an interactive HTML file with one call. Before you start:
  • Complete Quickstart to understand basic operations
  • Have some remembered data or any existing knowledge graph

What Graph Visualization Shows

  • Nodes (entities, types, chunks, summaries) with color coding
  • Edges with labels and weights; tooltips show extra edge properties
  • Interactive features: drag nodes, zoom/pan, hover edges for details

Code in Action

Step 1: Create Your Knowledge Graph

This starts from a clean state, then uses remember() to ingest the text and build the graph in one call.

Step 2: Generate Visualization

This creates an interactive HTML file with your knowledge graph. You can specify a custom path or use the default location.

Quick Options

Default Location

Custom Path

Tabs

Every rendered HTML file opens with a tab bar of four views — Graph, Schema, Memory, and Semantic — all computed from the same graph payload:
The default view: nodes and edges laid out by structure. Drag nodes, zoom/pan, and hover edges for details. On-screen controls let you:
  • Switch the layout — Story (fixed pipeline columns: Documents → Chunks → Entities → Types → Summaries), Flow (columns by processing order; vertical position settles by connectivity), or Force (a physics simulation where clusters emerge; drag nodes to rearrange).
  • Set the label budget — Key (landmark nodes + high-importance entities), All, or Off (hover to peek).
  • Recolor nodes by Type, Node set, or User, and zoom or fit to view.
A by-type summary of the rendered graph: instance counts per semantic type and the relationship distribution between types, computed at render time. The same projection is available as a standalone data API with its own HTTP endpoint — useful for driving dashboards without rendering HTML — see Schema Inventory.
A deterministic map of how the memory was built: documents, their chunks, and the entities extracted from them, plus the run timeline. Every list is ordered by keys intrinsic to the data, so the layout is reproducible and append-stable as the graph grows. Not to be confused with Memory Provenance, which is a separate projection of the relational database (tenants, users, agents, datasets, files) rendered to its own HTML file.
Instead of laying nodes out by their edges, the Semantic tab places each node at the 2‑D projection of its embedding, so semantically similar nodes sit together and clusters of related entities become visible at a glance. It reuses the vectors Cognee already stored during cognify() — nothing is re‑embedded at render time on the default LanceDB backend, and only 2‑D positions and precomputed neighbor lists are sent to the browser.Click Semantic in the tab bar, or append #semantic to the file URL to deep‑link straight to it. In the tab you can:
  • Cluster / Type — toggle recoloring nodes by semantic cluster or by ontology type.
  • Hover a node to light up its nearest neighbors and list its relations.
  • Legend entries filter to a single cluster or type; scroll or use the on‑screen controls to zoom.
  • Semantic ⇄ Structural — toggle between the pinned meaning‑space layout and a bounded force layout over the graph topology.
  • Recall overlay — light up the nodes a past recall query retrieved.
Choosing the projection. By default the layout uses PCA (pure‑numpy, sign‑stabilized), which is deterministic — the same graph always renders the same layout. To use UMAP instead, install it and opt in with an environment variable:
UMAP is an optional dependency and a lazy import — when umap-learn is not installed, the layout silently falls back to PCA.
The Semantic tab is best‑effort: if embeddings can’t be fetched or the projection fails, the tab shows a friendly empty state and the classic render is never affected. Nodes that have no stored vector are placed at the centroid of their positioned neighbors.
Behavior on large graphs. The semantic layout and clustering are bounded to 2000 nodes (SEMANTIC_NODE_CAP). Graphs above that are reduced with a deterministic seeded sample, so results are approximate at scale but stable across runs. When sampling kicks in, a warning is logged.When vectors are fetched, an info‑level log reports the join hit‑rate, e.g. resolved 128/150 node embeddings across 4 collection(s). If nothing resolves (a blank Semantic map), a warning names the missing collections and unmapped node types — the usual cause of a blank map is an id/collection‑name mismatch rather than a silent failure.

Tips

  • Large graphs: Rendering a very big graph can be slow. Consider building subsets (e.g., smaller datasets) before visualizing
  • Edge weights: If present, control line thickness; multiple weights are summarized and shown in tooltips
  • Static HTML: Files are static HTML; you can open them in any modern browser or share them as artifacts
Two companion projections summarize your memory without rendering every node — both run end-to-end without an LLM:
  • Schema Inventoryget_schema_inventory() summarizes the graph by semantic type: per-type counts, sample names, and relationship distribution.
  • Memory Provenancevisualize_memory_provenance() renders the ownership and data-flow story (Tenant → User → Agent → Dataset → file) from the relational database.

Additional information

visualize_graph() renders a bounded, relevant subgraph by default instead of the entire graph: it picks a small set of seed nodes, expands their k-hop neighborhood, and caps the result at max_nodes. This keeps renders fast and readable on large graphs. Pass full=True to restore the legacy whole-graph render.Seeds are resolved by priority — the first of these that produces nodes wins:
  1. seed_node_ids — explicit node ids you pass.
  2. recall_result — a recall() or search result whose graph provenance (used_graph_element_ids) seeds the subgraph, i.e. “show me the subgraph behind this answer”.
  3. query — a query string whose nearest vector hits (distance-ranked, nearest first) seed the subgraph.
  4. Highest-degree nodes — the fallback so a bare visualize_graph() call still shows a representative view.
If none of these resolve any seeds, an empty graph is rendered.The new parameters are keyword-only, so existing positional calls keep working unchanged:
When the neighborhood exceeds max_nodes, nodes are kept by hop distance from the seeds (seeds first) and edges survive only when both endpoints do, so no dangling edges remain.Over HTTP. GET /api/v1/visualize exposes the same controls as query params: full, query, seed_node_ids, neighborhood_depth, neighborhood_seed_top_k, and max_nodes (recall_result is Python-only). For example, GET /api/v1/visualize?dataset_id=<id>&full=true returns the whole-graph render.
If visualize_graph() logs No nodes found in the database (or the HTML opens empty) even though add() and cognify() ran without errors, the most common causes are:
  • Graph path mismatch. With the default Ladybug backend, the graph is stored on disk under <SYSTEM_ROOT_DIRECTORY>/databases/. By default, SYSTEM_ROOT_DIRECTORY is an absolute .cognee_system path under Cognee’s package root. In notebooks like Colab, it is safer to set explicit absolute paths before running add(), cognify(), and visualize_graph() so every step uses the same persisted location across cells and runtime changes:
  • cognify() produced no nodes. A run can finish “successfully” yet extract nothing — for example if no data was actually ingested, or graph extraction silently returned empty results (often a misconfigured or failing LLM/embedding provider). Don’t rely on the absence of an error; verify the graph was populated.
  • Data was pruned in between. Calling cognee.forget(everything=True) (or cognee.prune) after cognify() clears the graph, so a later visualize_graph() sees nothing.

Verify the graph was populated

Before visualizing, query the graph engine directly. get_graph_data() returns a (nodes, edges) tuple, and get_graph_metrics() reports the node/edge counts:
If len(nodes) is 0 here, the problem is upstream in add()/cognify() (or a path mismatch), not in visualization. A non-zero count from the same process that then reports No nodes found points to a path/config mismatch between steps.

Full Examples

Additional examples about Cognee are available on our github.
This simple example uses basic text data for demonstration. In practice, you can visualize complex knowledge graphs with thousands of nodes and relationships.

Core Concepts

Understand knowledge graph fundamentals

Custom Data Models

Learn about custom data models