github-actions[bot] commited on
Commit ·
83aa768
1
Parent(s): efe82cc
deploy: sync from GitHub 2026-05-04T13:33:44Z
Browse files- generate_heatmap.py +27 -31
generate_heatmap.py
CHANGED
|
@@ -1,9 +1,3 @@
|
|
| 1 |
-
"""
|
| 2 |
-
generate_heatmap.py
|
| 3 |
-
Generates a voltage heatmap for the IEEE 13-bus system with topology overlay.
|
| 4 |
-
Called by Julia: python3 generate_heatmap.py <output_path> <v1> <v2> ... <v13>
|
| 5 |
-
"""
|
| 6 |
-
|
| 7 |
import sys
|
| 8 |
import numpy as np
|
| 9 |
import matplotlib
|
|
@@ -12,7 +6,9 @@ import matplotlib.pyplot as plt
|
|
| 12 |
import matplotlib.image as mpimg
|
| 13 |
import matplotlib.patches as mpatches
|
| 14 |
from matplotlib.lines import Line2D
|
| 15 |
-
|
|
|
|
|
|
|
| 16 |
|
| 17 |
|
| 18 |
BUS_NAMES = {
|
|
@@ -64,13 +60,9 @@ def generate_heatmap(voltages, output_path, vmin=0.92, vmax=1.06, map_image="13b
|
|
| 64 |
xmin_d, xmax_d = -10, 1005
|
| 65 |
ymin_d, ymax_d = -10, 705
|
| 66 |
|
| 67 |
-
x = np.append(xs, [xmin_d, xmin_d, xmax_d, xmax_d])
|
| 68 |
-
y = np.append(ys, [ymin_d, ymax_d, ymin_d, ymax_d])
|
| 69 |
-
z = np.append(zs, [np.mean(zs)] * 4)
|
| 70 |
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
zi = griddata((x, y), z, (xi[None, :], yi[:, None]), method='cubic')
|
| 74 |
|
| 75 |
fig, ax = plt.subplots(figsize=(12, 8), frameon=False)
|
| 76 |
ax.set_xlim(xmin_d, xmax_d)
|
|
@@ -79,13 +71,6 @@ def generate_heatmap(voltages, output_path, vmin=0.92, vmax=1.06, map_image="13b
|
|
| 79 |
ax.set_axis_off()
|
| 80 |
|
| 81 |
# heatmap
|
| 82 |
-
im2 = ax.contourf(xi, yi, zi, levels=20,
|
| 83 |
-
vmin=vmin, vmax=vmax,
|
| 84 |
-
cmap='RdYlGn', alpha=0.75, zorder=1)
|
| 85 |
-
ax.contour(xi, yi, zi, levels=10,
|
| 86 |
-
vmin=vmin, vmax=vmax,
|
| 87 |
-
cmap='RdYlGn', alpha=0.3,
|
| 88 |
-
linewidths=0.5, zorder=2)
|
| 89 |
|
| 90 |
|
| 91 |
try:
|
|
@@ -129,10 +114,11 @@ def generate_heatmap(voltages, output_path, vmin=0.92, vmax=1.06, map_image="13b
|
|
| 129 |
bus_color = plt.cm.RdYlGn(t)
|
| 130 |
|
| 131 |
marker = 's' if bus_id == 1 else 'o'
|
| 132 |
-
ax.scatter(bx, by, s=200, color=bus_color,
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
|
|
|
| 136 |
v_color = '#dc2626' if v < 0.95 else '#d97706' if v > 1.05 else '#166534'
|
| 137 |
ax.text(bx, by + 30, f'Bus {bus_id}',
|
| 138 |
fontsize=7.5, fontweight='bold', color='#1e293b',
|
|
@@ -160,13 +146,22 @@ def generate_heatmap(voltages, output_path, vmin=0.92, vmax=1.06, map_image="13b
|
|
| 160 |
arrowprops=dict(arrowstyle='->', color='#0891b2', lw=1.5),
|
| 161 |
)
|
| 162 |
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
cbar.set_label('Voltage (p.u.)', fontsize=10, labelpad=8)
|
| 165 |
cbar.ax.tick_params(labelsize=8)
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
cbar.ax.axhline(y=(
|
| 169 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
|
| 171 |
|
| 172 |
|
|
@@ -198,7 +193,8 @@ def generate_heatmap(voltages, output_path, vmin=0.92, vmax=1.06, map_image="13b
|
|
| 198 |
handlelength=1.5, handleheight=1.0)
|
| 199 |
|
| 200 |
plt.tight_layout(pad=0.3)
|
| 201 |
-
plt.
|
|
|
|
| 202 |
plt.close()
|
| 203 |
print(f"[ok] saved {output_path}")
|
| 204 |
|
|
@@ -210,4 +206,4 @@ if __name__ == "__main__":
|
|
| 210 |
out = sys.argv[1]
|
| 211 |
volts = [float(v) for v in sys.argv[2:15]]
|
| 212 |
dc_bus = int(sys.argv[15]) if len(sys.argv) > 15 else None
|
| 213 |
-
generate_heatmap(volts, out, dc_bus_idx=dc_bus)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import sys
|
| 2 |
import numpy as np
|
| 3 |
import matplotlib
|
|
|
|
| 6 |
import matplotlib.image as mpimg
|
| 7 |
import matplotlib.patches as mpatches
|
| 8 |
from matplotlib.lines import Line2D
|
| 9 |
+
import matplotlib.cm as cm
|
| 10 |
+
import matplotlib.colors as mcolors
|
| 11 |
+
|
| 12 |
|
| 13 |
|
| 14 |
BUS_NAMES = {
|
|
|
|
| 60 |
xmin_d, xmax_d = -10, 1005
|
| 61 |
ymin_d, ymax_d = -10, 705
|
| 62 |
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
+
|
| 65 |
+
|
|
|
|
| 66 |
|
| 67 |
fig, ax = plt.subplots(figsize=(12, 8), frameon=False)
|
| 68 |
ax.set_xlim(xmin_d, xmax_d)
|
|
|
|
| 71 |
ax.set_axis_off()
|
| 72 |
|
| 73 |
# heatmap
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
|
| 75 |
|
| 76 |
try:
|
|
|
|
| 114 |
bus_color = plt.cm.RdYlGn(t)
|
| 115 |
|
| 116 |
marker = 's' if bus_id == 1 else 'o'
|
| 117 |
+
path_collection = ax.scatter(bx, by, s=200, color=bus_color,
|
| 118 |
+
marker=marker, edgecolors='#1e293b',
|
| 119 |
+
linewidths=2, zorder=8)
|
| 120 |
+
path_collection.set_gid(f"bus-node-{bus_id}")
|
| 121 |
+
|
| 122 |
v_color = '#dc2626' if v < 0.95 else '#d97706' if v > 1.05 else '#166534'
|
| 123 |
ax.text(bx, by + 30, f'Bus {bus_id}',
|
| 124 |
fontsize=7.5, fontweight='bold', color='#1e293b',
|
|
|
|
| 146 |
arrowprops=dict(arrowstyle='->', color='#0891b2', lw=1.5),
|
| 147 |
)
|
| 148 |
|
| 149 |
+
norm = mcolors.Normalize(vmin=vmin, vmax=vmax)
|
| 150 |
+
sm = plt.cm.ScalarMappable(cmap='RdYlGn', norm=norm)
|
| 151 |
+
sm.set_array([])
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
cbar = fig.colorbar(sm, ax=ax, shrink=0.6, pad=0.02, aspect=25)
|
| 155 |
cbar.set_label('Voltage (p.u.)', fontsize=10, labelpad=8)
|
| 156 |
cbar.ax.tick_params(labelsize=8)
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
cbar.ax.axhline(y=(0.95 - vmin) / (vmax - vmin), color='#ef4444', linewidth=1.5, linestyle='--')
|
| 160 |
+
cbar.ax.axhline(y=(1.05 - vmin) / (vmax - vmin), color='#f59e0b', linewidth=1.5, linestyle='--')
|
| 161 |
+
|
| 162 |
+
ax.set_facecolor('white')
|
| 163 |
+
fig.patch.set_facecolor('white')
|
| 164 |
+
|
| 165 |
|
| 166 |
|
| 167 |
|
|
|
|
| 193 |
handlelength=1.5, handleheight=1.0)
|
| 194 |
|
| 195 |
plt.tight_layout(pad=0.3)
|
| 196 |
+
plt.rcParams['svg.fonttype'] = 'none'
|
| 197 |
+
plt.savefig(output_path, format='svg', bbox_inches='tight', dpi=150, facecolor='white')
|
| 198 |
plt.close()
|
| 199 |
print(f"[ok] saved {output_path}")
|
| 200 |
|
|
|
|
| 206 |
out = sys.argv[1]
|
| 207 |
volts = [float(v) for v in sys.argv[2:15]]
|
| 208 |
dc_bus = int(sys.argv[15]) if len(sys.argv) > 15 else None
|
| 209 |
+
generate_heatmap(volts, out, dc_bus_idx=dc_bus)
|