# normal_gui_fixed_xy.py import tkinter as tk from tkinter import ttk import numpy as np import matplotlib import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg matplotlib.use('TkAgg') def generate_data(mu, sigma, n=1000): """Generate n samples from N(μ,σ²).""" return np.random.normal(loc=mu, scale=sigma, size=n) def draw_plot(ax, mu, sigma): """Redraw histogram + theoretical PDF while keeping axis limits fixed.""" ax.clear() data = generate_data(mu, sigma) # Histogram (density=True → area = 1) ax.hist(data, bins=30, density=True, alpha=0.6, color='steelblue') # Theoretical normal PDF evaluated on the fixed x‑range x = np.linspace(FIXED_XMIN, FIXED_XMAX, 300) pdf = (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(-0.5 * ((x - mu) / sigma) ** 2) ax.plot(x, pdf, color='darkred', lw=2) ax.set_title(f'Normal Distribution (μ={mu:.2f}, σ={sigma:.2f})') ax.set_xlabel('Value') ax.set_ylabel('Density') # Keep the pre‑defined limits ax.set_xlim(FIXED_XMIN, FIXED_XMAX) ax.set_ylim(FIXED_YMIN, FIXED_YMAX) ax.figure.canvas.draw_idle() # -------------------- Fixed axis limits -------------------- # X limits: wide enough for all µ (±10) plus 4 σ (max σ = 5) FIXED_XMIN = -15 FIXED_XMAX = 15 # Y limits: maximum PDF occurs at the smallest σ (0.1) # peak = 1/(σ·√(2π)) ≈ 3.989 for σ=0.1 → give a small margin FIXED_YMIN = 0 FIXED_YMAX = 4.5 # -------------------- Tkinter UI -------------------- root = tk.Tk() root.title("Normal Distribution Explorer (fixed X & Y axes)") fig, ax = plt.subplots(figsize=(5, 3), dpi=100) canvas = FigureCanvasTkAgg(fig, master=root) canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True) slider_frame = ttk.Frame(root, padding=10) slider_frame.pack(fill=tk.X) # µ (mean) slider mu_label = ttk.Label(slider_frame, text="μ (mean):") mu_label.grid(row=0, column=0, sticky="w") mu_var = tk.DoubleVar(value=0.0) mu_slider = ttk.Scale( slider_frame, from_=-10, to=10, orient="horizontal", variable=mu_var, command=lambda e: draw_plot(ax, mu_var.get(), sigma_var.get()) ) mu_slider.grid(row=0, column=1, sticky="ew", padx=5) # σ (std dev) slider sigma_label = ttk.Label(slider_frame, text="σ (std dev):") sigma_label.grid(row=1, column=0, sticky="w") sigma_var = tk.DoubleVar(value=1.0) sigma_slider = ttk.Scale( slider_frame, from_=0.1, to=5, orient="horizontal", variable=sigma_var, command=lambda e: draw_plot(ax, mu_var.get(), sigma_var.get()) ) sigma_slider.grid(row=1, column=1, sticky="ew", padx=5) slider_frame.columnconfigure(1, weight=1) # Initial plot with fixed limits draw_plot(ax, mu_var.get(), sigma_var.get()) root.mainloop()