#19 Pythonで始めるヒストグラムver1.1、チャレンジ AI×100業務(製造業)
チャレンジ#15では、ヒストグラムを描画しました。折角のヒストグラムですから、今回は種々の統計量を加えたものにします。
*それでは、スタートです。
*執筆者は以下を参照してください。
使ったツール・準備したこと
ChatGPT 4o
Visual Studio Code環境下でのPython
やってみたこと|コード・ステップ紹介
実行した内容の簡単な流れ
ChatGPT 4oにて以下のプロンプト
*前回のコードを参照しつつの会話です。
ヒストグラムの下に横向きの箱ひげ図を配置してください。
データは、グラフの右に移動して、以下の統計量や検定結果を表示してください 。
正規性検定(p値)、平均値、標準偏差、分散、歪度、尖度、データ数、最小値・・(略)
コードを実行すると、以下が描画されました。

*p値からデータは正規性を有しているようですね。
*95%信頼区間は平均に対してのものです。
やることが決まっている際は、このようなアプリは便利ですね。
今後の展開・アイデア
次回取り組みたいこと;
・先日、弊社のホームページ製作業者と打ち合わせた際の話です。
■ 今日のコード
import matplotlib
matplotlib.rcParams['font.family'] = 'Meiryo' # Windows の場合
import tkinter as tk
from tkinter import messagebox
import matplotlib.pyplot as plt
from matplotlib import rcParams
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np
import scipy.stats as stats
import re
# 日本語フォントの設定(文字化け対策)
# rcParams['font.family'] = 'IPAexGothic' # または 'MS Gothic', 'Yu Gothic', 'Noto Sans CJK JP' など
class HistogramApp:
def __init__(self, root):
self.root = root
self.root.title("ヒストグラム描画アプリ")
self.label = tk.Label(root, text="数値データを入力(最大30個、Excelからのコピペも可):")
self.label.pack()
self.entry = tk.Text(root, height=5, width=50)
self.entry.pack()
self.button = tk.Button(root, text="描画", command=self.draw_histogram)
self.button.pack()
self.result_frame = tk.Frame(root)
self.result_frame.pack(side=tk.RIGHT, padx=10)
self.result_text = tk.Text(self.result_frame, height=30, width=50)
self.result_text.pack()
self.canvas_frame = tk.Frame(root)
self.canvas_frame.pack(side=tk.LEFT)
def draw_histogram(self):
input_data = self.entry.get("1.0", tk.END).strip()
try:
# カンマ、スペース、改行、タブで区切る(Excelコピペ対応)
data_str_list = re.split(r'[\s,]+', input_data)
data = [float(x.strip()) for x in data_str_list if x.strip() != ""]
n = len(data)
if n > 30:
messagebox.showerror("エラー", "データは最大30個までです。")
return
# 基本統計量
mean = np.mean(data)
std_dev = np.std(data, ddof=1)
variance = np.var(data, ddof=1)
skewness = stats.skew(data)
kurtosis = stats.kurtosis(data)
_, p_value = stats.shapiro(data)
# 箱ひげ図用の統計量
minimum = np.min(data)
q1 = np.percentile(data, 25)
median = np.median(data)
q3 = np.percentile(data, 75)
maximum = np.max(data)
# 平均の95%信頼区間
ci_low, ci_high = stats.t.interval(0.95, df=n-1, loc=mean, scale=std_dev/np.sqrt(n))
# 統計結果を表示
self.result_text.delete("1.0", tk.END)
self.result_text.insert(tk.END, f"▶ 統計量・検定結果\n")
self.result_text.insert(tk.END, f"--------------------------\n")
self.result_text.insert(tk.END, f"データ数 : {n}\n\n")
self.result_text.insert(tk.END, f"正規性検定(p値) : {p_value:.4f}\n\n")
self.result_text.insert(tk.END, f"平均値 : {mean:.2f}\n")
self.result_text.insert(tk.END, f"標準偏差 : {std_dev:.2f}\n")
self.result_text.insert(tk.END, f"分散 : {variance:.2f}\n")
self.result_text.insert(tk.END, f"歪度 : {skewness:.2f}\n")
self.result_text.insert(tk.END, f"尖度 : {kurtosis:.2f}\n\n")
self.result_text.insert(tk.END, f"最小値 : {minimum:.2f}\n")
self.result_text.insert(tk.END, f"第1四分位数 : {q1:.2f}\n")
self.result_text.insert(tk.END, f"中央値 : {median:.2f}\n")
self.result_text.insert(tk.END, f"第3四分位数 : {q3:.2f}\n")
self.result_text.insert(tk.END, f"最大値 : {maximum:.2f}\n\n")
self.result_text.insert(tk.END, f"95%信頼区間 : [{ci_low:.2f}, {ci_high:.2f}]\n")
# グラフの描画(ヒストグラムと箱ひげ図)
fig = plt.figure(figsize=(8, 6))
gs = fig.add_gridspec(2, 1, height_ratios=[4, 1])
ax1 = fig.add_subplot(gs[0]) # ヒストグラム
ax1.hist(data, bins='auto', edgecolor='black')
ax1.axvline(mean, color='red', linestyle='dashed', linewidth=1.5, label=f"平均値: {mean:.2f}")
ax1.set_title("ヒストグラム")
ax1.set_ylabel("度数")
ax1.legend()
ax2 = fig.add_subplot(gs[1]) # 横向きの箱ひげ図
ax2.boxplot(
data,
vert=False,
patch_artist=True,
flierprops=dict(marker='+', color='red', markersize=8)
)
ax2.set_xlabel("値")
ax2.set_yticks([])
for widget in self.canvas_frame.winfo_children():
widget.destroy()
canvas = FigureCanvasTkAgg(fig, master=self.canvas_frame)
canvas.draw()
canvas.get_tk_widget().pack()
except ValueError:
messagebox.showerror("エラー", "数値を正しく入力してください(例: 10 20 30 または Excel からのコピペ)。")
if __name__ == "__main__":
root = tk.Tk()
app = HistogramApp(root)
root.mainloop()
