File size: 4,043 Bytes
b49bf63
 
 
 
 
 
 
f4edfd4
 
b49bf63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f4edfd4
 
 
 
 
b49bf63
f4edfd4
 
 
b49bf63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f4edfd4
b49bf63
 
 
 
 
 
 
 
 
f4edfd4
b49bf63
f4edfd4
 
b49bf63
 
 
 
 
 
f4edfd4
b49bf63
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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)