Skip to content

Instantly share code, notes, and snippets.

@FeepingCreature
Created June 25, 2024 23:47
Show Gist options
  • Save FeepingCreature/97217536585d88d371cd254e3980b551 to your computer and use it in GitHub Desktop.
Save FeepingCreature/97217536585d88d371cd254e3980b551 to your computer and use it in GitHub Desktop.
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