Unfaithful's picture
Update app.py
f4edfd4 verified
raw
history blame
4.04 kB
import random
import gradio as gr
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
from matplotlib.colors import to_hex
import threading
from io import BytesIO
from PIL import Image
lock = threading.Lock()
class Node:
def __init__(self, x, y, value=1.0):
self.x = x
self.y = y
self.value = value
self.connections = []
def connect(self, other_node):
if other_node not in self.connections:
self.connections.append(other_node)
def grow(self, increment=0.1):
self.value = min(self.value + increment, 5.0)
class Network:
def __init__(self):
self.nodes = []
def add_node(self, x, y):
with lock:
new_node = Node(x, y, value=random.uniform(1.0, 2.0))
self.nodes.append(new_node)
return new_node
def connect_nodes(self, distance_threshold=75):
with lock:
for node1 in self.nodes:
for node2 in self.nodes:
if node1 != node2 and self.distance(node1, node2) < distance_threshold:
node1.connect(node2)
def grow_nodes(self):
with lock:
for node in self.nodes:
node.grow()
def reset(self):
with lock:
self.nodes = []
def render(self):
with lock:
G = nx.Graph()
for i, node in enumerate(self.nodes):
G.add_node(i, pos=(node.x, node.y), size=node.value*100, color=self.get_color(node.value))
for i, node in enumerate(self.nodes):
for conn in node.connections:
j = self.nodes.index(conn)
G.add_edge(i, j)
pos = nx.get_node_attributes(G, 'pos')
sizes = [data['size'] for _, data in G.nodes(data=True)]
colors = [data['color'] for _, data in G.nodes(data=True)]
plt.figure(figsize=(8,8))
nx.draw(G, pos, with_labels=False, node_size=sizes, node_color=colors, edge_color="gray")
plt.axis('off')
plt.tight_layout()
# Save the plot to an in-memory buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Return a PIL image
return Image.open(buf)
@staticmethod
def get_color(value):
gradient = plt.cm.coolwarm
return to_hex(gradient(value / 5))
@staticmethod
def distance(node1, node2):
return np.sqrt((node1.x - node2.x)**2 + (node1.y - node2.y)**2)
network = Network()
def interact_network(x, y):
network.add_node(x, y)
network.connect_nodes()
network.grow_nodes()
return network.render()
def random_node():
x, y = random.randint(50, 450), random.randint(50, 450)
return interact_network(x, y)
def reset_network():
network.reset()
return network.render()
with gr.Blocks() as demo:
gr.Markdown("# Compassion Network (In-Memory Image Example)")
gr.Markdown("Add nodes and watch them grow and connect. Click Reset to start over.")
with gr.Row():
with gr.Column():
x_input = gr.Number(label="X Position", value=random.randint(50,450))
y_input = gr.Number(label="Y Position", value=random.randint(50,450))
add_button = gr.Button("Add Node")
random_button = gr.Button("Add Random Node")
reset_button = gr.Button("Reset Network")
with gr.Column():
graph_output = gr.Image(type="pil", interactive=False)
# Initialize the graph with an empty image
graph_output.update(value=network.render())
add_button.click(interact_network, inputs=[x_input, y_input], outputs=graph_output)
random_button.click(random_node, inputs=None, outputs=graph_output)
reset_button.click(reset_network, inputs=None, outputs=graph_output)
if __name__ == "__main__":
# Required for Hugging Face Spaces Docker
demo.launch(server_name="0.0.0.0", server_port=7860)