165 lines
5.1 KiB
Python
165 lines
5.1 KiB
Python
"""
|
|
Memory visualization module.
|
|
|
|
Provides visual representations of memory networks and search paths.
|
|
"""
|
|
import time
|
|
from typing import List, Dict, Any, Optional, Tuple
|
|
import networkx as nx
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib.patches import FancyBboxPatch
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
from rich.panel import Panel
|
|
from rich.layout import Layout
|
|
from rich.live import Live
|
|
from rich.text import Text
|
|
from rich import box
|
|
|
|
|
|
class MemoryVisualizer:
|
|
"""
|
|
Visualizes memory networks and search paths.
|
|
"""
|
|
|
|
def __init__(self):
|
|
"""Initialize the visualizer."""
|
|
self.console = Console()
|
|
|
|
def visualize_memory_graph(
|
|
self,
|
|
units: List[Dict[str, Any]],
|
|
links: List[Dict[str, Any]],
|
|
output_file: str = "memory_graph.png",
|
|
highlight_nodes: Optional[List[str]] = None,
|
|
):
|
|
"""
|
|
Create a visual representation of the memory graph.
|
|
|
|
Args:
|
|
units: List of memory units (id, text, context, etc.)
|
|
links: List of links (from_unit_id, to_unit_id, link_type, weight)
|
|
output_file: Output file path for the visualization
|
|
highlight_nodes: Optional list of node IDs to highlight
|
|
"""
|
|
# Create directed graph
|
|
G = nx.DiGraph()
|
|
|
|
# Add nodes
|
|
node_labels = {}
|
|
for unit in units:
|
|
unit_id = str(unit['id'])
|
|
# Truncate text for display
|
|
label = unit['text'][:40] + "..." if len(unit['text']) > 40 else unit['text']
|
|
G.add_node(unit_id)
|
|
node_labels[unit_id] = label
|
|
|
|
# Add edges
|
|
temporal_edges = []
|
|
semantic_edges = []
|
|
for link in links:
|
|
from_id = str(link['from_unit_id'])
|
|
to_id = str(link['to_unit_id'])
|
|
weight = link['weight']
|
|
link_type = link['link_type']
|
|
|
|
if link_type == 'temporal':
|
|
temporal_edges.append((from_id, to_id, weight))
|
|
else: # semantic
|
|
semantic_edges.append((from_id, to_id, weight))
|
|
|
|
G.add_edge(from_id, to_id, weight=weight, type=link_type)
|
|
|
|
# Create figure
|
|
fig, ax = plt.subplots(figsize=(20, 14))
|
|
ax.set_facecolor('#1a1a2e')
|
|
fig.patch.set_facecolor('#0f0f1e')
|
|
|
|
# Use spring layout for better visualization
|
|
pos = nx.spring_layout(G, k=2, iterations=50, seed=42)
|
|
|
|
# Draw temporal edges (blue)
|
|
if temporal_edges:
|
|
nx.draw_networkx_edges(
|
|
G, pos,
|
|
edgelist=[(e[0], e[1]) for e in temporal_edges],
|
|
edge_color='#4ecdc4',
|
|
alpha=0.6,
|
|
width=2,
|
|
arrows=True,
|
|
arrowsize=15,
|
|
arrowstyle='->',
|
|
connectionstyle='arc3,rad=0.1',
|
|
ax=ax
|
|
)
|
|
|
|
# Draw semantic edges (purple)
|
|
if semantic_edges:
|
|
nx.draw_networkx_edges(
|
|
G, pos,
|
|
edgelist=[(e[0], e[1]) for e in semantic_edges],
|
|
edge_color='#ff6b9d',
|
|
alpha=0.6,
|
|
width=2,
|
|
arrows=True,
|
|
arrowsize=15,
|
|
arrowstyle='->',
|
|
connectionstyle='arc3,rad=0.1',
|
|
ax=ax
|
|
)
|
|
|
|
# Determine node colors
|
|
node_colors = []
|
|
for node in G.nodes():
|
|
if highlight_nodes and node in highlight_nodes:
|
|
node_colors.append('#ffd93d') # Yellow for highlighted
|
|
else:
|
|
node_colors.append('#6c63ff') # Purple for normal
|
|
|
|
# Draw nodes
|
|
nx.draw_networkx_nodes(
|
|
G, pos,
|
|
node_color=node_colors,
|
|
node_size=3000,
|
|
alpha=0.9,
|
|
ax=ax
|
|
)
|
|
|
|
# Draw labels
|
|
nx.draw_networkx_labels(
|
|
G, pos,
|
|
node_labels,
|
|
font_size=8,
|
|
font_color='white',
|
|
font_weight='bold',
|
|
ax=ax
|
|
)
|
|
|
|
# Add legend
|
|
legend_elements = [
|
|
plt.Line2D([0], [0], color='#4ecdc4', lw=2, label='Temporal Links'),
|
|
plt.Line2D([0], [0], color='#ff6b9d', lw=2, label='Semantic Links'),
|
|
plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='#6c63ff',
|
|
markersize=10, label='Memory Unit', linestyle=''),
|
|
]
|
|
if highlight_nodes:
|
|
legend_elements.append(
|
|
plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='#ffd93d',
|
|
markersize=10, label='Highlighted', linestyle='')
|
|
)
|
|
|
|
ax.legend(handles=legend_elements, loc='upper left', facecolor='#2d2d44',
|
|
edgecolor='white', fontsize=10, labelcolor='white')
|
|
|
|
# Title
|
|
ax.set_title('Memory Network Graph\nTemporal + Semantic Architecture',
|
|
color='white', fontsize=16, fontweight='bold', pad=20)
|
|
|
|
ax.axis('off')
|
|
plt.tight_layout()
|
|
plt.savefig(output_file, dpi=150, facecolor='#0f0f1e')
|
|
plt.close()
|
|
|
|
self.console.print(f"[green]✓[/green] Memory graph saved to [cyan]{output_file}[/cyan]")
|
|
|
|
|