Spaces:
Runtime error
Runtime error
Update psychohistory.py
Browse files- psychohistory.py +18 -54
psychohistory.py
CHANGED
|
@@ -84,43 +84,21 @@ 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 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 |
-
"""
|
|
|
|
|
|
|
| 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,27 +109,28 @@ def draw_path_3d(G, path, filename='path_plot_3d.png', highlight_color='blue'):
|
|
| 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 |
-
#
|
| 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 |
-
#
|
| 143 |
for node, (x, y, z) in pos.items():
|
| 144 |
if node in path:
|
| 145 |
-
|
| 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,12 +183,9 @@ 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,28 +194,16 @@ def main(json_data):
|
|
| 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 |
-
|
| 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 |
-
|
| 243 |
if best_path:
|
| 244 |
draw_path_3d(G, best_path, 'best_path.png', 'blue')
|
| 245 |
if worst_path:
|
|
@@ -249,4 +213,4 @@ def main(json_data):
|
|
| 249 |
if shortest_path:
|
| 250 |
draw_path_3d(G, shortest_path, 'shortest_duration_path.png', 'purple')
|
| 251 |
|
| 252 |
-
return ('global_tree.png',
|
|
|
|
| 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 |
+
"""Draws only the specific path in 3D using networkx and matplotlib
|
| 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 |
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 |
+
# Draw edges
|
| 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 |
+
# Add labels to nodes
|
| 122 |
for node, (x, y, z) in pos.items():
|
| 123 |
if node in path:
|
| 124 |
+
ax.text(x, y, z, str(node), fontsize=12, color='black')
|
|
|
|
| 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') # Save to file with adjusted margins
|
| 133 |
+
plt.close() # Close the figure to free resources
|
| 134 |
|
| 135 |
|
| 136 |
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) # Build graph from the provided JSON data
|
| 189 |
|
| 190 |
draw_global_tree_3d(G, filename='global_tree.png')
|
| 191 |
|
|
|
|
| 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 |
+
print(f"Duration: {max(G.nodes[node]['pos'][0] for node in longest_path) - min(G.nodes[node]['pos'][0] for node in longest_path):.2f}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
if shortest_path:
|
| 204 |
print(f"\nPath with the shortest duration: {' -> '.join(map(str, shortest_path))}")
|
| 205 |
+
print(f"Duration: {max(G.nodes[node]['pos'][0] for node in shortest_path) - min(G.nodes[node]['pos'][0] for node in shortest_path):.2f}")
|
| 206 |
+
|
| 207 |
if best_path:
|
| 208 |
draw_path_3d(G, best_path, 'best_path.png', 'blue')
|
| 209 |
if worst_path:
|
|
|
|
| 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') # Return the filename of the global tree
|