# genesis/visualization.py import networkx as nx import matplotlib.pyplot as plt import io import base64 def _graph_to_image_bytes(G, layout_func=nx.spring_layout): """Helper: Convert NetworkX graph to PNG bytes.""" plt.figure(figsize=(8, 6)) pos = layout_func(G) nx.draw_networkx_nodes(G, pos, node_size=1500, node_color="#34d399", alpha=0.9) nx.draw_networkx_edges(G, pos, width=2, alpha=0.5, edge_color="#6b7280") nx.draw_networkx_labels(G, pos, font_size=10, font_family="sans-serif", font_color="white") plt.axis("off") buf = io.BytesIO() plt.savefig(buf, format="png", bbox_inches="tight") plt.close() buf.seek(0) return buf def generate_pathway_graph(entities, relationships): """ Create a pathway relationship graph for synthetic biology concepts. entities: list of strings relationships: list of dicts {source, target, type} Returns: file path to PNG """ G = nx.DiGraph() for entity in entities: G.add_node(entity) for rel in relationships: G.add_edge(rel["source"], rel["target"], label=rel["type"]) buf = _graph_to_image_bytes(G) file_path = "/tmp/pathway_graph.png" with open(file_path, "wb") as f: f.write(buf.read()) return file_path def generate_funding_network(companies): """ Create a funding network graph. companies: list of dicts {name, investors} Returns: file path to PNG """ G = nx.Graph() for comp in companies: company_node = f"🏢 {comp['name']}" G.add_node(company_node) investors = [i.strip() for i in comp["investors"].split(",")] for inv in investors: inv_node = f"💰 {inv}" G.add_node(inv_node) G.add_edge(company_node, inv_node) buf = _graph_to_image_bytes(G, layout_func=nx.kamada_kawai_layout) file_path = "/tmp/funding_network.png" with open(file_path, "wb") as f: f.write(buf.read()) return file_path