-
-
Save FeepingCreature/97217536585d88d371cd254e3980b551 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
import numpy as np | |
import matplotlib.pyplot as plt | |
from matplotlib.widgets import Slider, Button | |
def apply_strength(strength: float, steps: int, min_steps: int = 0) -> tuple[int, int]: | |
start_at_step = round(steps * (1 - strength)) | |
if min_steps and steps - start_at_step < min_steps: | |
steps = math.floor(min_steps / strength) | |
start_at_step = steps - min_steps | |
return steps, start_at_step | |
def plot_horizontal_segments(x, y, ax, label, color): | |
for i in range(1, len(x)): | |
if abs(y[i] - y[i-1]) < 1e-6: # Check if y values are nearly equal | |
ax.plot(x[i-1:i+1], y[i-1:i+1], color=color) | |
ax.scatter(x, y, color=color, s=10, label=label) | |
def update(): | |
fixed_steps = int(steps_slider.val) | |
min_steps = int(min_steps_slider.val) | |
highlight_strength = highlight_slider.val | |
ax1.clear() | |
ax2.clear() | |
original_strengths = np.linspace(0.01, 1.00, 100) | |
reconstructed_strengths_1 = [] | |
reconstructed_strengths_2 = [] | |
strength_differences = [] | |
highlight_reconstructed_1 = None | |
highlight_reconstructed_2 = None | |
highlight_difference = None | |
for strength in original_strengths: | |
steps_1, start_at_step_1 = apply_strength(strength, fixed_steps, min_steps) | |
reconstructed_strength_1 = (steps_1 - start_at_step_1) / steps_1 | |
reconstructed_strengths_1.append(reconstructed_strength_1) | |
steps_2, start_at_step_2 = apply_strength(reconstructed_strength_1, fixed_steps, min_steps) | |
reconstructed_strength_2 = (steps_2 - start_at_step_2) / steps_2 | |
reconstructed_strengths_2.append(reconstructed_strength_2) | |
strength_differences.append(reconstructed_strength_1 - reconstructed_strength_2) | |
if abs(strength - highlight_strength) < 0.005: | |
highlight_reconstructed_1 = reconstructed_strength_1 | |
highlight_reconstructed_2 = reconstructed_strength_2 | |
highlight_difference = reconstructed_strength_1 - reconstructed_strength_2 | |
ax1.plot(original_strengths, original_strengths, label='Original Strength', linestyle='--') | |
plot_horizontal_segments(original_strengths, reconstructed_strengths_1, ax1, '1st Reconstruction', 'g') | |
plot_horizontal_segments(original_strengths, reconstructed_strengths_2, ax1, '2nd Reconstruction', 'b') | |
ax1.set_ylabel('Strength') | |
ax1.set_title(f'Original vs Reconstructed Strengths (steps={fixed_steps}, min_steps={min_steps})') | |
ax1.legend() | |
ax1.grid(True) | |
if highlight_reconstructed_1 is not None: | |
ax1.plot(highlight_strength, highlight_strength, 'ro', markersize=8, label=f'Highlight ({highlight_strength:.2f})') | |
ax1.plot(highlight_strength, highlight_reconstructed_1, 'go', markersize=8) | |
ax1.plot(highlight_strength, highlight_reconstructed_2, 'bo', markersize=8) | |
ax1.legend() | |
ax1.annotate(f'{highlight_strength:.2f}', (highlight_strength, highlight_strength), textcoords="offset points", xytext=(0,10), ha='center') | |
ax1.annotate(f'{highlight_reconstructed_1:.2f}', (highlight_strength, highlight_reconstructed_1), textcoords="offset points", xytext=(0,10), ha='center') | |
ax1.annotate(f'{highlight_reconstructed_2:.2f}', (highlight_strength, highlight_reconstructed_2), textcoords="offset points", xytext=(0,10), ha='center') | |
ax2.plot(original_strengths, strength_differences, label='Difference (1st - 2nd)', color='red') | |
ax2.set_xlabel('Original Strength') | |
ax2.set_ylabel('Strength Difference') | |
ax2.set_title('Difference between 1st and 2nd Reconstruction') | |
ax2.legend() | |
ax2.grid(True) | |
if highlight_difference is not None: | |
ax2.plot(highlight_strength, highlight_difference, 'ro', markersize=8) | |
ax2.annotate(f'{highlight_difference:.4f}', (highlight_strength, highlight_difference), textcoords="offset points", xytext=(0,10), ha='center') | |
fig.canvas.draw_idle() | |
# Set up the figure and initial plot | |
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10), height_ratios=[3, 1], sharex=True) | |
plt.subplots_adjust(left=0.1, bottom=0.25, right=0.9, top=0.95) | |
# Set up sliders | |
ax_steps = plt.axes([0.1, 0.1, 0.65, 0.03]) | |
ax_min_steps = plt.axes([0.1, 0.06, 0.65, 0.03]) | |
ax_highlight = plt.axes([0.1, 0.02, 0.65, 0.03]) | |
steps_slider = Slider(ax_steps, 'Steps', 1, 50, valinit=8, valstep=1) | |
min_steps_slider = Slider(ax_min_steps, 'Min Steps', 0, 50, valinit=3, valstep=1) | |
highlight_slider = Slider(ax_highlight, 'Highlight', 0.01, 1.00, valinit=0.5, valstep=0.01) | |
# Create a timer for delayed update | |
timer = fig.canvas.new_timer(interval=300) # 300 milliseconds | |
timer.single_shot = True # Only trigger once per start() | |
def delayed_update(val): | |
timer.stop() | |
timer.start() | |
timer.add_callback(update) | |
steps_slider.on_changed(delayed_update) | |
min_steps_slider.on_changed(delayed_update) | |
highlight_slider.on_changed(delayed_update) | |
# Set up reset button | |
reset_ax = plt.axes([0.8, 0.025, 0.1, 0.04]) | |
reset_button = Button(reset_ax, 'Reset') | |
def reset(event): | |
steps_slider.reset() | |
min_steps_slider.reset() | |
highlight_slider.reset() | |
update() | |
reset_button.on_clicked(reset) | |
# Initial plot | |
update() | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment