#!/usr/bin/env python3 """ 📊 BOT SHAPE 3D VIEWER 📊 ═══════════════════════════════════════════════════════════════════════════════ Visualizes the spectral fingerprints generated by the Bot Shape Scanner. Outputs: - `bot_shapes.html`: Interactive 3D plot (open in browser) Usage: python bot_shape_viewer.py Gary Leckey | January 2026 ═══════════════════════════════════════════════════════════════════════════════ """ from aureon.core.aureon_baton_link import link_system as _baton_link; _baton_link(__name__) import json import os import sys import time try: import plotly.graph_objects as go from plotly.subplots import make_subplots except ImportError: print("❌ Plotly not found. Please install: pip install plotly") sys.exit(1) SNAPSHOT_FILE = "bot_shape_snapshot.json" OUTPUT_HTML = "bot_shapes.html" def render_viewer(): if not os.path.exists(SNAPSHOT_FILE): print(f"⚠️ Snapshot file '{SNAPSHOT_FILE}' not found. Run aureon_bot_shape_scanner.py first.") return try: with open(SNAPSHOT_FILE, "r") as f: data = json.load(f) except Exception as e: print(f"❌ Error reading snapshot: {e}") return shapes = data.get("shapes", []) if not shapes: print("⚠️ No shapes found in snapshot.") return print(f"🎨 Rendering 3D Bot Shapes for {len(shapes)} symbols...") feature_x = [] # Symbol Index feature_y = [] # Frequency feature_z = [] # Amplitude hover_text = [] colors = [] marker_sizes = [] symbol_map = {s['symbol']: i for i, s in enumerate(shapes)} for i, shape in enumerate(shapes): sym = shape['symbol'] freqs = shape['dominant_freqs'] amps = shape['amplitudes'] bot_class = shape['bot_class'] # Base color based on bot class base_color = 0 # Default if "HFT" in bot_class: base_color = 1 elif "MM" in bot_class: base_color = 2 elif "ACCUM" in bot_class: base_color = 3 for f, a in zip(freqs, amps): feature_x.append(i) # Symbol on X axis (categorical) feature_y.append(f) # Frequency on Y feature_z.append(a) # Amplitude (Magnitude) on Z hover_text.append( f"{sym}
" + f"Class: {bot_class}
" + f"Freq: {f:.2f}Hz
" + f"Amp: {a:.2f}" ) colors.append(base_color) marker_sizes.append(min(50, max(5, a * 20))) # Scale size by amplitude # Create 3D Scatter Plot fig = go.Figure(data=[go.Scatter3d( x=feature_x, y=feature_y, z=feature_z, mode='markers', marker=dict( size=marker_sizes, color=colors, colorscale='Viridis', opacity=0.8 ), text=hover_text, hoverinfo='text' )]) # Update layout tick_vals = list(range(len(shapes))) tick_text = [s['symbol'] for s in shapes] fig.update_layout( title=f"Aureon Bot Shape Quantum Telescope (Timestamp: {time.ctime(data['timestamp'])})", scene=dict( xaxis=dict( title='Asset (Reality Branch)', tickmode='array', tickvals=tick_vals, ticktext=tick_text ), yaxis=dict(title='Frequency (Hz) - The "Loop"'), zaxis=dict(title='Amplitude (Magnitude)'), ), margin=dict(r=0, l=0, b=0, t=40) ) fig.write_html(OUTPUT_HTML) print(f"✅ 3D View saved to: {os.path.abspath(OUTPUT_HTML)}") if __name__ == "__main__": while True: render_viewer() print("Waiting 10s for next update...") time.sleep(10)