如何将matplotlib直方图嵌入到tkinter GUI中?

时间:2014-03-03 03:08:52

标签: python user-interface python-3.x matplotlib

我有这个程序,从特定参数(上限,样本大小)中随机生成的数字中间列表创建直方图。我怎样才能使得创建的直方图出现在比例尺正上方的tkinter GUI中?我到处寻找,仍然无法弄明白。提前致谢!我正在使用python 3。

奖金问题(无需回答,但如果您愿意,它会有所帮助):我如何制作它以便比例控制number_lists的值(基本上是生成中值的次数)然后通过添加新计算的中位数来更新直方图的外观?

import random
import matplotlib, sys
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import numpy as np
from tkinter import *
from tkinter import ttk


#root
root = Tk()
root.title("Sample Size and the Normal Distribution")

#mainframe
mainframe = ttk.Frame(root, padding = "3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

def create_list(sampleSize, upperLimit):
    numbList = []
    sampleSize = int(sample.get())
    upperLimit = int(upper.get())
    while sampleSize > 0:
        sampleSize -= 1
        randomNum = random.randrange(0,upperLimit+1)
        numbList.append(randomNum)
    numbList.sort(key=int)
    return numbList

def medians_variance(median_list):
    sum_of_medians = sum(median_list)
    variance = sum_of_medians / len(median_list)
    return variance


def median(numbList):

        srtd = sorted(numbList)
        mid = len(numbList)//2
        if len(numbList) % 2 == 0:
            return (srtd[mid-1] + srtd[mid]) / 2.0
        else:
            return srtd[mid]


def main():

    number_lists = 10
    lists = []
    median_list = []

    binsize = 10

    for i in range(number_lists):
        lists.append(create_list(sampleSize, upperLimit))

    for current_list in lists:
        current_median = median(current_list)
        median_list.append(current_median)
        median_list.sort(key=float)


    plt.hist(median_list, binsize)

    plt.xlabel('Median Value', fontsize = 15)
    plt.ylabel('Frequency', fontsize = 15)

    plt.show()


    med = median(median_list)
    std = np.std(median_list)
    var = (std**2)


#sampleSize Entry
sample = StringVar()
sampleSize = ttk.Entry(mainframe, width = 7, textvariable = sample)
sampleSize.grid(column = 2, row = 1, sticky =(W, E))

#upperLimit Entry
upper = StringVar()
upperLimit = ttk.Entry(mainframe, width = 7, textvariable = upper)
upperLimit.grid(column = 2, row = 3, sticky = (W, E))

#binsize Entry
Bin = StringVar()
binsize = ttk.Entry(mainframe, width = 7, textvariable = Bin)
binsize.grid(column = 2, row = 5, sticky = (W, E))

#sampleSize and upperLimit Labels
ttk.Label(mainframe, text="Sample Size ").grid(column = 1, row = 1, sticky = W)
ttk.Label(mainframe, text="Upper Limit ").grid(column = 1, row = 3, sticky = W)
ttk.Label(mainframe, text="Bin Size").grid(column = 1, row = 5, sticky = W)

#histogram embed
f = Figure(figsize = (5,4), dpi=100)

#button for new histogram
button = ttk.Button(mainframe, text="New Histogram", command=main).grid(column=1, row=7, sticky=W)

#scale
scale = Scale(mainframe, from_=0, to=10, orient=HORIZONTAL,length=400).grid(column = 5, row = 12, sticky= S)

for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)

sampleSize.focus()
upperLimit.focus()
root.bind('<Return>', main)

root.mainloop()

1 个答案:

答案 0 :(得分:3)

创建一个FigureCanvasTkAgg对象并将其放在框架内:

f = Figure(figsize=(5,4), dpi=100)
canvas = FigureCanvasTkAgg(f, master=mainframe)
canvas.get_tk_widget().grid(row=1, column=3, rowspan=6)

main中,不使用plt,而是使用图对象f

p = f.gca()
p.hist(median_list, binsize)
p.set_xlabel('Median Value', fontsize = 15)
p.set_ylabel('Frequency', fontsize = 15)
canvas.show()

enter image description here

顺便说一下,滑动网格略有修改以获得以上结果:

scale = Scale(mainframe, from_=0, to=10, orient=HORIZONTAL,length=400)
scale.grid(column=3, row=12, sticky=S)