0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Interactive Code (ipywidgets + PNG/PDF Auto-Save)

0
Posted at
# ============================================
# Interactive Three-step Tsurukame Visualization
# Matplotlib + ipywidgets (Google Colab)
# ============================================

!pip install ipywidgets
from ipywidgets import interact, FloatSlider, IntSlider, Button, HBox, VBox, Output
from IPython.display import display, clear_output
import matplotlib.pyplot as plt
import numpy as np

# --------------------------------------------------
# Output area for plot
# --------------------------------------------------
plot_out = Output()

# --------------------------------------------------
# Draw function
# --------------------------------------------------
def draw_tsurukame(point_base, point_std, point_app,
                   num_base, num_std, num_app,
                   baseline):

    with plot_out:
        clear_output(wait=True)

        # Derived values
        remain_base = point_base - baseline
        remain_std  = point_std  - baseline
        remain_app  = point_app  - baseline

        avg_remain = (remain_base + remain_std) / 2
        diff_app   = remain_app - avg_remain

        total_score = point_base*num_base + point_std*num_std + point_app*num_app
        remain_total = remain_base*num_base + remain_std*num_std + remain_app*num_app

        # Prepare figure
        fig = plt.figure(figsize=(16,10))
        plt.suptitle("Three-step Tsurukame Visualization (Interactive)", fontsize=20)

        xs = [1, 5, 9]
        widths = [num_base, num_std, num_app]
        labels = [f"Base ({num_base})", f"Standard ({num_std})", f"Applied ({num_app})"]

        # --------------------------------------------------
        # 1. Triple Tower
        # --------------------------------------------------
        ax1 = plt.subplot(2,2,1)
        ax1.set_title("① Triple Tower (Original Situation)")

        heights = [point_base, point_std, point_app]
        colors = ["#4A90E2", "#7ED321", "#D0021B"]

        for i in range(3):
            ax1.bar(xs[i], heights[i], width=widths[i], color=colors[i])
            ax1.text(xs[i], heights[i] + 0.4, f"{heights[i]} pt", ha="center", fontsize=11)

        ax1.set_xlim(0, 12)
        ax1.set_ylim(0, max(heights)+2)
        ax1.set_xticks(xs)
        ax1.set_xticklabels(labels)
        ax1.text(0.5, max(heights), f"Total Score = {total_score}", fontsize=11)

        # --------------------------------------------------
        # 2. Baseline removal
        # --------------------------------------------------
        ax2 = plt.subplot(2,2,2)
        ax2.set_title("② Remove Baseline")

        # baseline parts
        for i in range(3):
            ax2.bar(xs[i], baseline, width=widths[i], color="#DDDDDD")

        # remain parts
        ax2.bar(xs[0], remain_base, bottom=baseline, width=widths[0], color="#4A90E2")
        ax2.bar(xs[1], remain_std,  bottom=baseline, width=widths[1], color="#7ED321")
        ax2.bar(xs[2], remain_app,  bottom=baseline, width=widths[2], color="#D0021B")

        ax2.axhline(baseline, linestyle="--", color="black")
        ax2.text(0.5, baseline+remain_app+1.5,
                 f"Remaining Score = {remain_total}", fontsize=11)

        ax2.set_xlim(0, 12)
        ax2.set_ylim(0, baseline+remain_app+3)
        ax2.set_xticks(xs)
        ax2.set_xticklabels(labels)

        # --------------------------------------------------
        # 3. Averaging (Base+Standard merged)
        # --------------------------------------------------
        ax3 = plt.subplot(2,2,3)
        ax3.set_title("③ Average Merge (Base + Standard)")

        ax3.bar(3, avg_remain, width=num_base+num_std, color="#8888FF")
        ax3.text(3, avg_remain+0.4,
                 f"Avg Remain = {avg_remain:.2f} pt", ha="center")

        ax3.bar(10, remain_app, width=num_app, color="#D0021B")
        ax3.text(10, remain_app+0.4,
                 f"{remain_app} pt", ha="center")

        ax3.axhline(avg_remain, linestyle="--", color="black")
        ax3.set_xlim(0, 14)
        ax3.set_ylim(0, remain_app+3)
        ax3.set_xticks([3,10])
        ax3.set_xticklabels([f"Base+Std ({num_base+num_std})",
                             f"Applied ({num_app})"])

        # --------------------------------------------------
        # 4. Twin Tower (hypothesis method)
        # --------------------------------------------------
        ax4 = plt.subplot(2,2,4)
        ax4.set_title("④ Twin Tower (Hypothesis Method)")

        # average tower
        ax4.bar(3, avg_remain, width=num_base+num_std, color="#8888FF")

        # applied tower: base + difference
        ax4.bar(10, avg_remain, width=num_app, color="#FFAAAA")
        ax4.bar(10, diff_app,  width=num_app, bottom=avg_remain, color="#FF4444")

        ax4.axhline(avg_remain, linestyle="--", color="black")

        total_diff = diff_app * num_app

        ax4.text(0.5, diff_app + avg_remain + 1.2,
                 f"Total difference = {total_diff:.2f} pt", fontsize=12)
        ax4.text(0.5, diff_app + avg_remain + 0.2,
                 f"{total_diff:.2f} ÷ {diff_app:.2f} = {num_app}",
                 fontsize=14, fontweight="bold")

        ax4.set_xlim(0, 14)
        ax4.set_ylim(0, diff_app + avg_remain + 3)
        ax4.set_xticks([3,10])
        ax4.set_xticklabels([f"Average ({num_base+num_std})",
                             f"Applied ({num_app})"])

        plt.tight_layout(rect=[0, 0, 1, 0.94])
        plt.show()

# --------------------------------------------------
# Interactive sliders
# --------------------------------------------------
sl_point_base = IntSlider(value=5, min=1, max=20, description="Base pt")
sl_point_std  = IntSlider(value=10, min=1, max=20, description="Std pt")
sl_point_app  = IntSlider(value=12, min=1, max=20, description="App pt")

sl_num_base = IntSlider(value=3, min=1, max=10, description="Base n")
sl_num_std  = IntSlider(value=3, min=1, max=10, description="Std n")
sl_num_app  = IntSlider(value=2, min=1, max=10, description="App n")

sl_baseline = IntSlider(value=5, min=0, max=20, description="Baseline")

# --------------------------------------------------
# Buttons for Reset / Save
# --------------------------------------------------
btn_reset = Button(description="Reset", button_style="warning")
btn_save_png = Button(description="Save PNG", button_style="success")
btn_save_pdf = Button(description="Save PDF", button_style="primary")

def on_reset_clicked(b):
    sl_point_base.value = 5
    sl_point_std.value  = 10
    sl_point_app.value  = 12
    sl_num_base.value = 3
    sl_num_std.value  = 3
    sl_num_app.value  = 2
    sl_baseline.value = 5

def on_save_png_clicked(b):
    plt.savefig("/content/tsurukame_plot.png", dpi=200)
    print("Saved PNG → /content/tsurukame_plot.png")

def on_save_pdf_clicked(b):
    plt.savefig("/content/tsurukame_plot.pdf")
    print("Saved PDF → /content/tsurukame_plot.pdf")

btn_reset.on_click(on_reset_clicked)
btn_save_png.on_click(on_save_png_clicked)
btn_save_pdf.on_click(on_save_pdf_clicked)

# --------------------------------------------------
# Display UI
# --------------------------------------------------
ui = VBox([
    HBox([sl_point_base, sl_point_std, sl_point_app]),
    HBox([sl_num_base, sl_num_std, sl_num_app]),
    HBox([sl_baseline]),
    HBox([btn_reset, btn_save_png, btn_save_pdf])
])

display(ui)
display(plot_out)

# --------------------------------------------------
# Connect interactive plotting
# --------------------------------------------------
interact(
    draw_tsurukame,
    point_base=sl_point_base,
    point_std=sl_point_std,
    point_app=sl_point_app,
    num_base=sl_num_base,
    num_std=sl_num_std,
    num_app=sl_num_app,
    baseline=sl_baseline
);
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?