Spaces:
Running
Running
cryptocalypse
commited on
Commit
•
cc62867
1
Parent(s):
5a5d6f8
Update psychohistory.py
Browse files- psychohistory.py +54 -18
psychohistory.py
CHANGED
@@ -84,21 +84,43 @@ def find_paths(G):
|
|
84 |
return best_path, best_mean_prob, worst_path, worst_mean_prob, longest_duration_path, shortest_duration_path
|
85 |
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
def draw_path_3d(G, path, filename='path_plot_3d.png', highlight_color='blue'):
|
88 |
-
"""
|
89 |
-
and saves the figure to a file."""
|
90 |
-
# Create a subgraph containing only the nodes and edges of the path
|
91 |
H = G.subgraph(path).copy()
|
92 |
-
|
93 |
pos = nx.get_node_attributes(G, 'pos')
|
|
|
94 |
|
95 |
-
# Get data for 3D visualization
|
96 |
x_vals, y_vals, z_vals = zip(*[pos[node] for node in path])
|
97 |
|
98 |
fig = plt.figure(figsize=(16, 12))
|
99 |
ax = fig.add_subplot(111, projection='3d')
|
100 |
|
101 |
-
# Assign colors to nodes based on probability
|
102 |
node_colors = []
|
103 |
for node in path:
|
104 |
prob = G.nodes[node]['pos'][1]
|
@@ -109,28 +131,27 @@ def draw_path_3d(G, path, filename='path_plot_3d.png', highlight_color='blue'):
|
|
109 |
else:
|
110 |
node_colors.append('green')
|
111 |
|
112 |
-
# Draw nodes
|
113 |
ax.scatter(x_vals, y_vals, z_vals, c=node_colors, s=700, edgecolors='black', alpha=0.7)
|
114 |
|
115 |
-
#
|
116 |
for edge in H.edges():
|
117 |
x_start, y_start, z_start = pos[edge[0]]
|
118 |
x_end, y_end, z_end = pos[edge[1]]
|
119 |
ax.plot([x_start, x_end], [y_start, y_end], [z_start, z_end], color=highlight_color, lw=2)
|
120 |
|
121 |
-
#
|
122 |
for node, (x, y, z) in pos.items():
|
123 |
if node in path:
|
124 |
-
|
|
|
125 |
|
126 |
-
# Set labels and title
|
127 |
ax.set_xlabel('Time (weeks)')
|
128 |
ax.set_ylabel('Event Probability')
|
129 |
ax.set_zlabel('Event Number')
|
130 |
ax.set_title('3D Event Tree - Path')
|
131 |
|
132 |
-
plt.savefig(filename, bbox_inches='tight')
|
133 |
-
plt.close()
|
134 |
|
135 |
|
136 |
def draw_global_tree_3d(G, filename='global_tree.png'):
|
@@ -183,9 +204,12 @@ def draw_global_tree_3d(G, filename='global_tree.png'):
|
|
183 |
plt.savefig(filename, bbox_inches='tight') # Save to file with adjusted margins
|
184 |
plt.close() # Close the figure to free resources
|
185 |
|
|
|
|
|
|
|
186 |
def main(json_data):
|
187 |
G = nx.DiGraph()
|
188 |
-
build_graph_from_json(json_data, G)
|
189 |
|
190 |
draw_global_tree_3d(G, filename='global_tree.png')
|
191 |
|
@@ -194,16 +218,28 @@ def main(json_data):
|
|
194 |
if best_path:
|
195 |
print(f"\nPath with the highest average probability: {' -> '.join(map(str, best_path))}")
|
196 |
print(f"Average probability: {best_mean_prob:.2f}")
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
if worst_path:
|
198 |
print(f"\nPath with the lowest average probability: {' -> '.join(map(str, worst_path))}")
|
199 |
print(f"Average probability: {worst_mean_prob:.2f}")
|
|
|
200 |
if longest_path:
|
201 |
print(f"\nPath with the longest duration: {' -> '.join(map(str, longest_path))}")
|
202 |
-
|
|
|
|
|
|
|
|
|
|
|
203 |
if shortest_path:
|
204 |
print(f"\nPath with the shortest duration: {' -> '.join(map(str, shortest_path))}")
|
205 |
-
|
206 |
-
|
207 |
if best_path:
|
208 |
draw_path_3d(G, best_path, 'best_path.png', 'blue')
|
209 |
if worst_path:
|
@@ -213,4 +249,4 @@ def main(json_data):
|
|
213 |
if shortest_path:
|
214 |
draw_path_3d(G, shortest_path, 'shortest_duration_path.png', 'purple')
|
215 |
|
216 |
-
return ('global_tree.png','best_path.png','longest_duration_path.png')
|
|
|
84 |
return best_path, best_mean_prob, worst_path, worst_mean_prob, longest_duration_path, shortest_duration_path
|
85 |
|
86 |
|
87 |
+
def calculate_angles_between_points(path, pos):
|
88 |
+
"""Calcula los ángulos en radianes y grados entre puntos consecutivos en los planos XZ, XY y ZY."""
|
89 |
+
angles = {'xz': [], 'xy': [], 'zy': []}
|
90 |
+
|
91 |
+
for i in range(1, len(path)):
|
92 |
+
# Obtener las posiciones de los puntos consecutivos
|
93 |
+
x1, y1, z1 = pos[path[i-1]]
|
94 |
+
x2, y2, z2 = pos[path[i]]
|
95 |
+
|
96 |
+
# Cálculo del ángulo en el plano XZ
|
97 |
+
delta_x = x2 - x1
|
98 |
+
delta_z = z2 - z1
|
99 |
+
angle_xz = math.atan2(delta_z, delta_x) # Radianes
|
100 |
+
angles['xz'].append((angle_xz, math.degrees(angle_xz))) # Convertir a grados
|
101 |
+
|
102 |
+
# Cálculo del ángulo en el plano XY
|
103 |
+
delta_y = y2 - y1
|
104 |
+
angle_xy = math.atan2(delta_y, delta_x) # Radianes
|
105 |
+
angles['xy'].append((angle_xy, math.degrees(angle_xy))) # Convertir a grados
|
106 |
+
|
107 |
+
# Cálculo del ángulo en el plano ZY
|
108 |
+
angle_zy = math.atan2(delta_y, delta_z) # Radianes
|
109 |
+
angles['zy'].append((angle_zy, math.degrees(angle_zy))) # Convertir a grados
|
110 |
+
|
111 |
+
return angles
|
112 |
+
|
113 |
def draw_path_3d(G, path, filename='path_plot_3d.png', highlight_color='blue'):
|
114 |
+
"""Dibuja solo un path específico en 3D y guarda la imagen con etiquetas."""
|
|
|
|
|
115 |
H = G.subgraph(path).copy()
|
|
|
116 |
pos = nx.get_node_attributes(G, 'pos')
|
117 |
+
labels = nx.get_node_attributes(G, 'label') # Obtener etiquetas
|
118 |
|
|
|
119 |
x_vals, y_vals, z_vals = zip(*[pos[node] for node in path])
|
120 |
|
121 |
fig = plt.figure(figsize=(16, 12))
|
122 |
ax = fig.add_subplot(111, projection='3d')
|
123 |
|
|
|
124 |
node_colors = []
|
125 |
for node in path:
|
126 |
prob = G.nodes[node]['pos'][1]
|
|
|
131 |
else:
|
132 |
node_colors.append('green')
|
133 |
|
|
|
134 |
ax.scatter(x_vals, y_vals, z_vals, c=node_colors, s=700, edgecolors='black', alpha=0.7)
|
135 |
|
136 |
+
# Dibujar aristas
|
137 |
for edge in H.edges():
|
138 |
x_start, y_start, z_start = pos[edge[0]]
|
139 |
x_end, y_end, z_end = pos[edge[1]]
|
140 |
ax.plot([x_start, x_end], [y_start, y_end], [z_start, z_end], color=highlight_color, lw=2)
|
141 |
|
142 |
+
# Agregar etiquetas
|
143 |
for node, (x, y, z) in pos.items():
|
144 |
if node in path:
|
145 |
+
label = labels.get(node, str(node))
|
146 |
+
ax.text(x, y, z, label, fontsize=12, color='black')
|
147 |
|
|
|
148 |
ax.set_xlabel('Time (weeks)')
|
149 |
ax.set_ylabel('Event Probability')
|
150 |
ax.set_zlabel('Event Number')
|
151 |
ax.set_title('3D Event Tree - Path')
|
152 |
|
153 |
+
plt.savefig(filename, bbox_inches='tight')
|
154 |
+
plt.close()
|
155 |
|
156 |
|
157 |
def draw_global_tree_3d(G, filename='global_tree.png'):
|
|
|
204 |
plt.savefig(filename, bbox_inches='tight') # Save to file with adjusted margins
|
205 |
plt.close() # Close the figure to free resources
|
206 |
|
207 |
+
|
208 |
+
|
209 |
+
|
210 |
def main(json_data):
|
211 |
G = nx.DiGraph()
|
212 |
+
build_graph_from_json(json_data, G)
|
213 |
|
214 |
draw_global_tree_3d(G, filename='global_tree.png')
|
215 |
|
|
|
218 |
if best_path:
|
219 |
print(f"\nPath with the highest average probability: {' -> '.join(map(str, best_path))}")
|
220 |
print(f"Average probability: {best_mean_prob:.2f}")
|
221 |
+
best_angles = calculate_angles_between_points(best_path, nx.get_node_attributes(G, 'pos'))
|
222 |
+
print("\nAngles for the most probable path:")
|
223 |
+
print(f"XZ plane angles (radians, degrees): {best_angles['xz']}")
|
224 |
+
print(f"XY plane angles (radians, degrees): {best_angles['xy']}")
|
225 |
+
print(f"ZY plane angles (radians, degrees): {best_angles['zy']}")
|
226 |
+
|
227 |
if worst_path:
|
228 |
print(f"\nPath with the lowest average probability: {' -> '.join(map(str, worst_path))}")
|
229 |
print(f"Average probability: {worst_mean_prob:.2f}")
|
230 |
+
|
231 |
if longest_path:
|
232 |
print(f"\nPath with the longest duration: {' -> '.join(map(str, longest_path))}")
|
233 |
+
longest_angles = calculate_angles_between_points(longest_path, nx.get_node_attributes(G, 'pos'))
|
234 |
+
print("\nAngles for the longest duration path:")
|
235 |
+
print(f"XZ plane angles (radians, degrees): {longest_angles['xz']}")
|
236 |
+
print(f"XY plane angles (radians, degrees): {longest_angles['xy']}")
|
237 |
+
print(f"ZY plane angles (radians, degrees): {longest_angles['zy']}")
|
238 |
+
|
239 |
if shortest_path:
|
240 |
print(f"\nPath with the shortest duration: {' -> '.join(map(str, shortest_path))}")
|
241 |
+
|
242 |
+
# Dibujar paths y añadir etiquetas a los nodos
|
243 |
if best_path:
|
244 |
draw_path_3d(G, best_path, 'best_path.png', 'blue')
|
245 |
if worst_path:
|
|
|
249 |
if shortest_path:
|
250 |
draw_path_3d(G, shortest_path, 'shortest_duration_path.png', 'purple')
|
251 |
|
252 |
+
return ('global_tree.png', 'best_path.png', 'longest_duration_path.png',longest_angles,best_angles)
|