-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsugarscape_visualiser.py
More file actions
126 lines (95 loc) · 3.96 KB
/
sugarscape_visualiser.py
File metadata and controls
126 lines (95 loc) · 3.96 KB
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
import json
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.widgets import Slider
import numpy as np
import traceback
DATA_DIR = "data"
grid = np.array([])
loaded_steps = 0
def unpack(v):
# Function is required to convert agent variable states from array to scalars due to bug in RC3
# I.e. [123] to 123
return v[0] if isinstance(v, list) else v
def load_data(state_count):
global grid
global loaded_steps
try:
for i in range(state_count+1):
file_path = f"{DATA_DIR}/{i}.json"
with open(file_path, 'r', encoding='utf-8') as file:
data = json.load(file)
agents = data.get("agents", {}).get("agent", {}).get("default", [])
if not agents:
print("No agent data found.")
return
# Determine grid size
max_x = unpack(max(agent.get('x', 0) for agent in agents))
max_y = unpack(max(agent.get('y', 0) for agent in agents))
if not grid.any():
grid = np.zeros((max_x + 1, max_y + 1, state_count+1))
for agent in agents:
x, y = unpack(agent.get('x', 0)), unpack(agent.get('y', 0))
env_sugar_level = unpack(agent.get('env_sugar_level', 0))
agent_id = unpack(agent.get('agent_id', -1))
if agent_id != -1:
grid[x, y, i] = -1 # Mark active agents with -1
else:
grid[x, y, i] = env_sugar_level
loaded_steps = state_count
except Exception as e:
print(f"Error reading JSON file: {e}")
print(traceback.format_exc())
def plot_state(state):
"""Reads a JSON file and plots sugar levels and active agents."""
# if grid is empty force reload of data
if not grid.any() or loaded_steps < state:
load_data(state)
# Plotting
plt.figure(figsize=(8, 6))
cmap = plt.cm.viridis
cmap.set_under(color='red') # Mark active agents with a distinct color
im = plt.imshow(grid[:,:,state], origin='lower', cmap=cmap, interpolation='nearest', vmin=0)
#plot
plt.title(f"Agent Sugar Level and Active Agents Step {state}")
plt.colorbar(im)
plt.show()
def animate_states(state_count):
"""Reads a JSON file and plots sugar levels and active agents."""
global ani
# if grid is empty force reload of data
if not grid.any():
load_data(state_count)
fig, ax = plt.subplots()
cmap = plt.cm.viridis
cmap.set_under(color='red') # Mark active agents with a distinct color
ims = [] # ims is a list of lists, each row is a list of artists to draw in the
for i in range(state_count):
im = ax.imshow(grid[:,:,i], animated=True, cmap=cmap, interpolation='nearest', vmin=0.0)
if i == 0:
ax.imshow(grid[:,:,i], animated=True, cmap=cmap, interpolation='nearest', vmin=0.0) # show an initial one first
ims.append([im])
ani = animation.ArtistAnimation(fig, ims, interval=100, blit=True, repeat_delay=1000)
# Plotting
plt.colorbar(im, ax=ax)
plt.show()
def display_states(state_count):
"""Reads a JSON file and plots sugar levels and active agents."""
global im
global slider
im = slider = None
# if grid is empty force reload of data
if not grid.any():
load_data(state_count)
fig, ax = plt.subplots()
cmap = plt.cm.viridis
cmap.set_under(color='red') # Mark active agents with a distinct color
ims = [] # ims is a list of lists
im = ax.imshow(grid[:,:,0], cmap=cmap, interpolation='nearest', vmin=0.0)
ax_depth = plt.axes([0.23, 0.02, 0.56, 0.04])
slider = Slider(ax_depth, 'iteration', 0, grid.shape[2]-1, valinit=0)
update_slider = lambda v: im.set_data(grid[:, :, int(round(v))])
slider.on_changed(update_slider)
# Plotting
plt.colorbar(im, ax=ax)
plt.show()