from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
flat_params_over_steps_arr = np.asarray(flat_params_over_steps, dtype=float)
vertex_xy_over_steps = flat_params_over_steps_arr.reshape(
flat_params_over_steps_arr.shape[0], -1, 2
)
vertex_total_delta = np.linalg.norm(vertex_xy_over_steps[-1] - vertex_xy_over_steps[0], axis=1)
final_vertex_xy = vertex_xy_over_steps[-1]
zoom_half_width = 0.1
zoom_half_height = 0.1
n_focus_spots = 4
focus_spots = []
excluded_vertices = np.zeros(vertex_total_delta.shape, dtype=bool)
for _ in range(n_focus_spots):
available_delta = np.where(excluded_vertices, -np.inf, vertex_total_delta)
focus_vertex_idx = int(np.argmax(available_delta))
focus_x = float(final_vertex_xy[focus_vertex_idx, 0])
focus_y = float(final_vertex_xy[focus_vertex_idx, 1])
focus_delta = float(vertex_total_delta[focus_vertex_idx])
focus_spots.append((focus_vertex_idx, focus_x, focus_y, focus_delta))
in_cutout = (np.abs(final_vertex_xy[:, 0] - focus_x) <= zoom_half_width) & (
np.abs(final_vertex_xy[:, 1] - focus_y) <= zoom_half_height
)
excluded_vertices |= in_cutout
zoom_legend_handles = [
Line2D([0], [0], color="0.7", lw=1.2, label="before optimization"),
Line2D([0], [0], color="crimson", lw=1.2, label="after optimization"),
]
fig_diff = plt.figure(figsize=(12.8, 8.4), constrained_layout=True)
grid = fig_diff.add_gridspec(2, 3, width_ratios=(1.45, 1.0, 1.0))
ax_diff = fig_diff.add_subplot(grid[:, 0])
ax_zooms = [
fig_diff.add_subplot(grid[0, 1]),
fig_diff.add_subplot(grid[0, 2]),
fig_diff.add_subplot(grid[1, 1]),
fig_diff.add_subplot(grid[1, 2]),
]
for structure in contour_structures_over_steps[0]:
xy = np.asarray(structure.geometry.vertices, dtype=float)
xy_closed = np.vstack([xy, xy[0]])
for ax_zoom in ax_zooms:
ax_zoom.plot(xy_closed[:, 0], xy_closed[:, 1], color="0.7", lw=1.0)
for structure in contour_structures_over_steps[-1]:
xy = np.asarray(structure.geometry.vertices, dtype=float)
xy_closed = np.vstack([xy, xy[0]])
ax_diff.plot(xy_closed[:, 0], xy_closed[:, 1], color="crimson", lw=1.0)
for ax_zoom in ax_zooms:
ax_zoom.plot(xy_closed[:, 0], xy_closed[:, 1], color="crimson", lw=1.0)
ax_diff.set_title("final contour overview")
for spot_num, (_, focus_x, focus_y, _) in enumerate(focus_spots, start=1):
rect = Rectangle(
(focus_x - zoom_half_width, focus_y - zoom_half_height),
2 * zoom_half_width,
2 * zoom_half_height,
fill=False,
edgecolor="dodgerblue",
linewidth=1.2,
)
ax_diff.add_patch(rect)
ax_diff.text(
focus_x,
focus_y,
f"{spot_num}",
color="dodgerblue",
ha="center",
va="center",
)
ax_diff.set_aspect("equal")
ax_diff.set_xlim(-lx / 2, lx / 2)
ax_diff.set_ylim(-ly / 2, ly / 2)
ax_diff.set_xlabel("x (um)")
ax_diff.set_ylabel("y (um)")
for spot_num, (ax_zoom, (_, focus_x, focus_y, focus_delta)) in enumerate(
zip(ax_zooms, focus_spots),
start=1,
):
ax_zoom.set_title(f"spot {spot_num}")
ax_zoom.set_aspect("equal")
ax_zoom.set_xlim(focus_x - zoom_half_width, focus_x + zoom_half_width)
ax_zoom.set_ylim(focus_y - zoom_half_height, focus_y + zoom_half_height)
ax_zoom.set_xlabel("x (um)")
ax_zoom.set_ylabel("y (um)")
ax_zoom.legend(
handles=zoom_legend_handles,
loc="upper right",
fontsize=7,
framealpha=0.9,
borderpad=0.25,
handlelength=1.8,
)
plt.show()