PyQt5で統計分布を表示するGUIを作ってみた!

PyQt5を用いて分布を表示するGUIを作ってみた.
きっかけは, Bayes更新をみんな手軽に体感できないかなと思ったから.
パラメーターをいじると図が更新されていきます.
Pause 押して値を変えて, Updateを押すと, その値の分布が表示されます.
気分が向いたらプログラムに関する解説文書きます.

コードをコピーしてpythonで動かせば回るはず!
< 環境 >
macOS Mojave version 10.14.6
anaconda3-5.3.1
cycler==0.10.0
kiwisolver==1.0.1
matplotlib==3.0.3
numpy==1.16.2
pyparsing==2.4.0
PyQt5==5.12.1
PyQt5-sip==4.19.15
python-dateutil==2.8.0
scipy==1.2.1
six==1.12.0


# usr/bin/python3
# coding:utf-8

'''
This program is for looking at each statistical distribution 
'''

import sys
import os 
import numpy as np
import matplotlib.pyplot as plt
import time 

from PyQt5 import QtWidgets 
from PyQt5.QtCore import Qt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas 


import glob
from scipy.stats import norm
from scipy.stats import expon
from scipy.stats import gamma
from scipy.stats import beta
from scipy.stats import poisson

### plot setting
plt.rcParams["axes.grid"] = True
plt.rcParams["grid.linestyle"] = "--"
plt.rcParams["grid.linewidth"] = 0.3

def GetNDigit(v,n = 5):
    v = str(v) 
    if len(v.replace(".","")) < n + 1:
        return(v)
    else:
        ind = 0 
        s = ""
        for i in range(1000):
            if v[i] == "." :
                s += v[i]
                continue
            else:
                s += v[i]
                ind += 1
            if ind >= n:
                return(s)
            

class Application(QtWidgets.QMainWindow):
    
    def __init__(self):
        super().__init__()

        self.initUI()
    
        # initialize File list
        self.SetFileList()
        self.initFigure()
        self.initControlWidget()
        self.initResultWidget()
        self.initInfoWidget()
        self.UpdateDist()


        
        # define event when a file is changed 
        self.FileList.itemSelectionChanged.connect(self.FileListChanged)

    # initialize UI 
    def initUI(self):
        # For FigureWidget
        self.FigureWidget = QtWidgets.QWidget(self)
        # make FigureLayout. This FigureLayout will be added by vbox.
        self.FigureLayout = QtWidgets.QVBoxLayout(self.FigureWidget)
        # delett margin 
        self.FigureLayout.setContentsMargins(0,0,0,0)
        

        # make FileList,Info,Control,and Result widgests 
        self.FileList      = QtWidgets.QListWidget(self)
        self.ControlWidget = QtWidgets.QWidget(self)
        self.ResultWidget  = QtWidgets.QWidget(self)

        self.InfoWidget    = QtWidgets.QWidget(self)
        self.InfoLayout = QtWidgets.QVBoxLayout(self.InfoWidget)
        self.InfoLayout.setContentsMargins(0,0,0,0)

        # alinment 
        nx = 1000
        ny = 650
        self.setGeometry(0,0,nx,ny)
        self.FileList.setGeometry(0,0,nx*0.2,ny)
        self.FigureWidget.setGeometry(nx*0.2,0,nx*0.5,ny*0.7) 
        self.InfoWidget.setGeometry(nx*0.7,0,nx*0.3,ny*0.7)
        self.ControlWidget.setGeometry(nx*0.2,ny*0.7,nx*0.6,ny*0.3)
        self.ResultWidget.setGeometry(nx*0.8,ny*0.7,nx*0.2,ny*0.3)

    def initFigure(self):
        # make Figure 
        self.Figure = plt.figure()
        # add Figure to FigureCanvas 
        self.FigureCanvas = FigureCanvas(self.Figure)

        # add FigureCanvas to Layout
        self.FigureLayout.addWidget(self.FigureCanvas)
        
        self.axis = self.Figure.add_subplot(1,1,1)
#        self.axis.plot(1,1)
        
    def initControlWidget(self):
        
        self.LineLayout = QtWidgets.QGridLayout()
        # creat Option widgets
        self.SelectType = QtWidgets.QComboBox(self)

        self.SetSelectType("continuous")
        self.SelectType.highlighted.connect(self.UpdateDist)

        self.initExpoControl()
        
        self.PauseButton = QtWidgets.QPushButton("Pause")
        self.PauseButton.setCheckable(True)
        self.OneUpdateButton= QtWidgets.QPushButton("Update")
        self.ClearButton = QtWidgets.QPushButton("Clear")

        self.OptionLayout = QtWidgets.QHBoxLayout()
        self.OptionLayout.addWidget(self.SelectType)
        self.OptionLayout.addStretch(1)
        self.OptionLayout.addWidget(self.PauseButton)
        self.OptionLayout.addWidget(self.OneUpdateButton)
        self.OptionLayout.addWidget(self.ClearButton)
        
        # signals for Option widgets
        self.OneUpdateFlag = 0
        def flag1() : self.OneUpdateFlag = 1
        def flag0() : self.OneUpdateFlag = 0
        self.OneUpdateButton.clicked.connect(flag1)
        self.OneUpdateButton.clicked.connect(self.AddDist)
        self.OneUpdateButton.clicked.connect(flag0)
        self.ClearButton.clicked.connect(self.UpdateDist)
        
        
        # set this Control in ControlWidget
        self.vbox = QtWidgets.QVBoxLayout(self.ControlWidget)
        self.vbox.addLayout(self.LineLayout)
        self.vbox.addLayout(self.OptionLayout)
        self.vbox.addStretch(1)

    def SetSelectType(self,mode):
        if self.SelectType != None:
            self.SelectType.clear()
        if mode == "continuous":
            self.SelectType.addItem("Probability Density Function")
            self.SelectType.addItem("Cumulative Density Function")
        if mode == "discrete":
            self.SelectType.addItem("Probability Mass Function")
            self.SelectType.addItem("Cumulative Density Function")

    def initControl(self):

        self.slds = []
        self.minimumSpinBoxs = []
        self.maximumSpinBoxs = []
        self.binSpinBoxs = []
        self.CurrentValues = []
        for i in range(self.npar):
            self.sld = QtWidgets.QSlider(Qt.Horizontal, self)
            self.sld.setFocusPolicy(Qt.NoFocus)
            self.sld.setGeometry(30, 40, 100, 30)
            
            self.sld.setFocusPolicy(Qt.StrongFocus)
            self.sld.setTickPosition(QtWidgets.QSlider.TicksBothSides)
            self.sld.setTickInterval(30)
            self.sld.setSingleStep(1)
            self.sld.setMinimum(1)
            self.sld.setMaximum(10)

            # minimum and maximum box
            self.minimumSpinBox = QtWidgets.QDoubleSpinBox()
            self.minimumSpinBox.setRange(self.MinSpinRange[i][0],self.MinSpinRange[i][1])
            self.minimumSpinBox.setSingleStep(1)
            self.minimumSpinBox.setValue(self.MinSpinInit[i])
            self.maximumSpinBox = QtWidgets.QDoubleSpinBox()
            self.maximumSpinBox.setRange(self.MaxSpinRange[i][0],self.MaxSpinRange[i][1])
            self.maximumSpinBox.setSingleStep(1)
            self.maximumSpinBox.setValue(self.MaxSpinInit[i])

            # set Bin Box 
            self.binSpinBox  = QtWidgets.QSpinBox()
            self.binSpinBox.setRange(1,10000)
            self.binSpinBox.setSingleStep(1)
            self.binSpinBox.setValue(10)

            # Showing current value         
            self.CurrentValue= QtWidgets.QDoubleSpinBox()
            self.CurrentValue.setRange(self.CurrentRange[i][0],self.CurrentRange[i][1])
            self.CurrentValue.setSingleStep(0.01)
            self.CurrentValue.setValue(self.CurrentInit[i])
            
            # add to 's 
            self.slds.append(self.sld)
            self.minimumSpinBoxs.append(self.minimumSpinBox)
            self.maximumSpinBoxs.append(self.maximumSpinBox)
            self.binSpinBoxs.append(self.binSpinBox)
            self.CurrentValues.append(self.CurrentValue)

        ##### setting signals #####
        def f0(): self.ParameterIndex = 0
        def f1(): self.ParameterIndex = 1
        def f2(): self.ParameterIndex = 2
        def f3(): self.ParameterIndex = 3
        for i in range(self.npar):
            if i ==0:
                self.minimumSpinBoxs[i].valueChanged.connect(f0)
                self.maximumSpinBoxs[i].valueChanged.connect(f0)
                self.binSpinBoxs[i].valueChanged.connect(f0)
                self.slds[i].valueChanged.connect(f0)
            if i == 1:
                self.minimumSpinBoxs[i].valueChanged.connect(f1)
                self.maximumSpinBoxs[i].valueChanged.connect(f1)
                self.binSpinBoxs[i].valueChanged.connect(f1)
                self.slds[i].valueChanged.connect(f1)
            if i == 2:
                self.minimumSpinBoxs[i].valueChanged.connect(f2)
                self.maximumSpinBoxs[i].valueChanged.connect(f2)
                self.binSpinBoxs[i].valueChanged.connect(f2)
                self.slds[i].valueChanged.connect(f2)
            if i == 3:
                self.minimumSpinBoxs[i].valueChanged.connect(f3)
                self.maximumSpinBoxs[i].valueChanged.connect(f3)
                self.binSpinBoxs[i].valueChanged.connect(f3)
                self.slds[i].valueChanged.connect(f3)

            self.minimumSpinBoxs[i].valueChanged.connect(self.CalcCurrentValue)
            self.maximumSpinBoxs[i].valueChanged.connect(self.CalcCurrentValue)
            self.binSpinBoxs[i].valueChanged.connect(self.slds[i].setMaximum)

            self.slds[i].valueChanged.connect(self.CalcCurrentValue)
            # for updating figure
            self.CurrentValues[i].valueChanged.connect(self.AddDist)

        ###### set layout of control box #####
        self.LineLayout.addWidget(QtWidgets.QLabel("pars"),0,0)
        self.LineLayout.addWidget(QtWidgets.QLabel("Min"),0,1)
        self.LineLayout.addWidget(QtWidgets.QLabel("Max"),0,2)
        self.LineLayout.addWidget(QtWidgets.QLabel("Bin"),0,3)
        self.LineLayout.addWidget(QtWidgets.QLabel("Slider"),0,4)
        self.LineLayout.addWidget(QtWidgets.QLabel("Value"),0,5)

        ParName = ["tau"]
        for i in range(self.npar):
            self.LineLayout.addWidget(QtWidgets.QLabel(self.ParName[i]),i+1,0)
            self.LineLayout.addWidget(self.minimumSpinBoxs[i],i+1,1)
            self.LineLayout.addWidget(self.maximumSpinBoxs[i],i+1,2)
            self.LineLayout.addWidget(self.binSpinBoxs[i],i+1,3)
            self.LineLayout.addWidget(self.slds[i],i+1,4)
            self.LineLayout.addWidget(self.CurrentValues[i],i+1,5)

    def initExpoControl(self):
        # for parameter index
        self.ParameterIndex = 0
        # for initialize Comobox
        self.SetSelectType("continuous")

        self.npar = 1

        self.MinSpinRange = [[-100000,10000]]
        self.MaxSpinRange =  self.MinSpinRange
        self.MinSpinInit = [1]
        self.MaxSpinInit = [3]
        self.CurrentRange = self.MinSpinRange
        self.CurrentInit = [1]
        self.ParName = ["tau"]

        self.initControl()


    def initNormControl(self):
        # for parameter index
        self.ParameterIndex = 0
        self.SetSelectType("continuous")

        self.npar = 2

        self.MinSpinRange = [[-100000,10000],[0,10000]]
        self.MaxSpinRange =  self.MinSpinRange
        self.MinSpinInit = [-5,1]
        self.MaxSpinInit = [5,5]
        self.CurrentRange = self.MinSpinRange
        self.CurrentInit = [0,1]
        self.ParName = ["mu","sigma"]

        self.initControl()

    def initGammaControl(self):
        # for parameter index
        self.ParameterIndex = 0
        self.SetSelectType("continuous")

        self.npar = 2

        self.MinSpinRange = [[0,10000],[0,10000]]
        self.MaxSpinRange =  self.MinSpinRange
        self.MinSpinInit = [1,1]
        self.MaxSpinInit = [5,5]
        self.CurrentRange = self.MinSpinRange
        self.CurrentInit = [1,1]
        self.ParName = ["shape(a)","rate(b)"]

        self.initControl()


    def initBetaControl(self):
        # for parameter index
        self.ParameterIndex = 0
        self.SetSelectType("continuous")

        self.npar = 2

        self.MinSpinRange = [[0,10000],[0,10000]]
        self.MaxSpinRange =  self.MinSpinRange
        self.MinSpinInit = [1,1]
        self.MaxSpinInit = [10,10]
        self.CurrentRange = self.MinSpinRange
        self.CurrentInit = [1,1]
        self.ParName = ["a","b"]

        self.initControl()

    def initPoissonControl(self):

        # for parameter index
        self.ParameterIndex = 0
        # for initialize Comobox
        self.SetSelectType("discrete")

        self.npar = 1

        self.MinSpinRange = [[0,10000]]
        self.MaxSpinRange =  self.MinSpinRange
        self.MinSpinInit = [1]
        self.MaxSpinInit = [10]
        self.CurrentRange = self.MinSpinRange
        self.CurrentInit = [1]
        self.ParName = ["lambda"]

        self.initControl()


    #### for ControlWidget #####    
    def CalcCurrentValue(self):
        ind = self.ParameterIndex
        min_ = self.minimumSpinBoxs[ind].value()
        max_ = self.maximumSpinBoxs[ind].value()
        bin_ = self.binSpinBoxs[ind].value()
        sld_v = self.slds[ind].value()

        CurrentValue_ = np.linspace(min_,max_,bin_)[sld_v-1]
        self.CurrentValues[ind].setValue(CurrentValue_)

    #### for ResultWidget##### 
    def initResultWidget(self):

        self.MeanDisplay = QtWidgets.QLineEdit()
        self.VarianceDisplay = QtWidgets.QLineEdit()
        self.MedianDisplay = QtWidgets.QLineEdit()
        self.MeanDisplay.setReadOnly(True)
        self.VarianceDisplay.setReadOnly(True)
        self.MedianDisplay.setReadOnly(True)


        SubLineLayout = QtWidgets.QGridLayout()
        SubLineLayout.addWidget(QtWidgets.QLabel("Mean"),0,0)
        SubLineLayout.addWidget(self.MeanDisplay,0,1)
        SubLineLayout.addWidget(QtWidgets.QLabel("Variance"),1,0)
        SubLineLayout.addWidget(self.VarianceDisplay,1,1)
        SubLineLayout.addWidget(QtWidgets.QLabel("Median"),2,0)
        SubLineLayout.addWidget(self.MedianDisplay,2,1)

        self.SubWidgetLayout = QtWidgets.QVBoxLayout(self.ResultWidget)
        self.SubWidgetLayout.addLayout(SubLineLayout)
        self.SubWidgetLayout.addStretch(1)

    def initInfoWidget(self):
        # make Figure 
        self.InfoFigure= plt.figure()
        # add Figure to FigureCanvas 
        self.InfoCanvas = FigureCanvas(self.InfoFigure)
        # add InfoCanvas to Layout
        self.InfoLayout.addWidget(self.InfoCanvas)

        self.AxisInfo = self.InfoFigure.add_subplot(1,1,1)
        
        self.initExpoInfo()

        self.AxisInfo.get_xaxis().set_visible(False)
        self.AxisInfo.get_yaxis().set_visible(False)
        self.AxisInfo.spines["right"].set_visible(False)
        self.AxisInfo.spines["left"].set_visible(False)
        self.AxisInfo.spines["top"].set_visible(False)
        self.AxisInfo.spines["bottom"].set_visible(False)
        
    def initExpoInfo(self):
        self.AxisInfo.clear()
        characters = ["PDF","CDF","Mean","Variance","Median"]

        expressions ={} 
        expressions["PDF"]  = r"$frac{1}{tau}e^{-frac{x}{tau}}$" 
        expressions["CDF"]  = r"$1 - e^{-frac{x}{tau}} $"
        expressions["Mean"] = r"$tau$"
        expressions["Variance"] = r"$tau^2 $"
        expressions["Median"] = r"$tau ln(2) $"
        for i, ch in enumerate(characters):
            self.AxisInfo.text(-0.1,1- i*0.1,ch)
            self.AxisInfo.text(0.2,1- i*0.1,":")
            self.AxisInfo.text(0.25,1- i*0.1, expressions[ch],fontsize = 12)

        self.InfoCanvas.draw()

    def initNormInfo(self):
        self.AxisInfo.clear()
        characters = ["PDF","CDF","Mean","Variance","Median"]

        expressions ={} 
        expressions["PDF"]  = r"$frac{1}{sqrt{2pi sigma^2}}exp(-frac{1}{2}(frac{x - mu}{sigma})^2)$" 
        expressions["CDF"]  = r"$ frac{1}{sqrt{2pi sigma^2}}int_{-infty}^x exp(-frac{1}{2}(frac{x-mu}{sigma})^2)dx $"
        expressions["Mean"] = r"$mu$"
        expressions["Variance"] = r"$sigma^2 $"
        expressions["Median"] = r"$mu $"
        for i, ch in enumerate(characters):
            self.AxisInfo.text(-0.1,1- i*0.1,ch)
            self.AxisInfo.text(0.2,1- i*0.1,":")
            self.AxisInfo.text(0.25,1- i*0.1, expressions[ch],fontsize = 10)

        self.InfoCanvas.draw()

    def initGammaInfo(self):
        self.AxisInfo.clear()
        characters = ["PDF","CDF","Mean","Variance","Median"]

        expressions ={} 
        expressions["PDF"]  = r"$frac{b^a}{Gamma(a)}x^{a-1}e^{-bx}$" 
        expressions["CDF"]  = r"$ frac{b^a}{Gamma(a)}int_0^x x^{a-1}e^{-bx}dx$"
        expressions["Mean"] = r"$frac{a}{b}$"
        expressions["Variance"] = r"$frac{a}{b^2} $"
        expressions["Median"] = "not simple"
        for i, ch in enumerate(characters):
            self.AxisInfo.text(-0.1,1- i*0.1,ch)
            self.AxisInfo.text(0.2,1- i*0.1,":")
            self.AxisInfo.text(0.25,1- i*0.1, expressions[ch],fontsize = 10)

        self.InfoCanvas.draw()

    def initBetaInfo(self):
        self.AxisInfo.clear()
        characters = ["PDF","CDF","Mean","Variance","Median"]

        expressions ={} 
        expressions["PDF"]  = r"$frac{Gamma(a+b)}{Gamma(a)Gamma(b)}x^{a-1}(1-x)^{b-1}$"
        expressions["CDF"]  = r"$frac{Gamma(a+b)}{Gamma(a)Gamma(b)}int_0^{infty} x^{a-1}(1-x)^{b-1}dx $"
        expressions["Mean"] = r"$frac{a}{a+b}$"
        expressions["Variance"] = r"$frac{ab}{(a+b)^2(a+b+1) }$"
        expressions["Median"] = r"$approx frac{a - frac{1}{3}}{a+b - frac{2}{3}}$"
        for i, ch in enumerate(characters):
            self.AxisInfo.text(-0.1,1- i*0.1,ch)
            self.AxisInfo.text(0.2,1- i*0.1,":")
            self.AxisInfo.text(0.25,1- i*0.1, expressions[ch],fontsize = 10)

        self.InfoCanvas.draw()

    def initPoissonInfo(self):
        self.AxisInfo.clear()
        characters = ["PDF","CDF","Mean","Variance","Median"]

        expressions ={} 
        expressions["PDF"]  = r"$frac{lambda^k e^{-lambda}}{k!}$"
        expressions["CDF"]  = r"$e^{-lambda}sum_{i=0}^{lfloor k rfloor}frac{lambda^i}{i!}$"
        expressions["Mean"] = r"$lambda$"
        expressions["Variance"] = r"$lambda$"
        expressions["Median"] = r"$approx lfloor lambda + 1/3 - 0.02/lambda rfloor$"
        for i, ch in enumerate(characters):
            self.AxisInfo.text(-0.1,1- i*0.1,ch)
            self.AxisInfo.text(0.2,1- i*0.1,":")
            self.AxisInfo.text(0.25,1- i*0.1, expressions[ch],fontsize = 10)

        self.InfoCanvas.draw()

    def UpdateDist(self):
        self.axis.cla()
        self.FigureCanvas.draw()
        self.AddDist()

            
    def AddDist(self):
        if self.PauseButton.isChecked() and self.OneUpdateFlag == 0 :
            return(0)
       
        if self.FileName == "Exponential":
            self.AddExponential()
        if self.FileName == "Normal":
            self.AddNormal()
        if self.FileName == "Gamma":
            self.AddGamma()
        if self.FileName == "Beta":
            self.AddBeta()
        if self.FileName == "Poisson":
            self.AddPoisson()
            
    def AddExponential(self):
        tau = self.CurrentValues[0].value()
        
        #self.axis = self.Figure.add_subplot(1,1,1)
        ex = expon(scale=tau)
        x = np.linspace(ex.ppf(0.05),ex.ppf(0.95),1000)
        if self.SelectType.currentText() == "Probability Density Function":
            y = ex.pdf(x)
        elif self.SelectType.currentText() == "Cumulative Density Function":
            y = ex.cdf(x)
        else:
            x = 1
            y = 1

        # add to graph
        cm = plt.get_cmap("rainbow")
        n_bin = self.binSpinBox.value()
        i_th = self.sld.value()
        
        self.axis.plot(x,y ,color = cm(i_th/n_bin))
        self.axis.set_title("Exponential Distribution")
        self.FigureCanvas.draw()

        ### for obtaining mean,variance, and median
        self.MeanDisplay.setText(GetNDigit( tau))
        self.VarianceDisplay.setText(GetNDigit(tau**2))
        self.MedianDisplay.setText(GetNDigit(tau*np.log(2)))

    def AddNormal(self):
        mu = self.CurrentValues[0].value()
        sigma = self.CurrentValues[1].value()
        
        nm= norm(loc = mu,scale = sigma)
        x = np.linspace(nm.ppf(0.05),nm.ppf(0.95),1000)
        if self.SelectType.currentText() == "Probability Density Function":
            y = nm.pdf(x)
        elif self.SelectType.currentText() == "Cumulative Density Function":
            y = nm.cdf(x)

        # add to graph
        cm = plt.get_cmap("rainbow")
        n_bin = self.binSpinBox.value()
        i_th = self.sld.value()
        
        self.axis.plot(x,y,color = cm(i_th/n_bin))
        self.axis.set_title("Normal Distribution")
        self.FigureCanvas.draw()

        ### for obtaining mean,variance, and median
        self.MeanDisplay.setText(GetNDigit( mu))
        self.VarianceDisplay.setText(GetNDigit(sigma**2))
        self.MedianDisplay.setText(GetNDigit(mu))

    def AddGamma(self):
        a = self.CurrentValues[0].value()
        b = self.CurrentValues[1].value()
        scale = 1/b
        
        gm= gamma(a = a,scale = scale)
        x = np.linspace(gm.ppf(0.05),gm.ppf(0.95),1000)
        if self.SelectType.currentText() == "Probability Density Function":
            y = gm.pdf(x)
        elif self.SelectType.currentText() == "Cumulative Density Function":
            y = gm.cdf(x)

        # add to graph
        cm = plt.get_cmap("rainbow")
        n_bin = self.binSpinBox.value()
        i_th = self.sld.value()
        
        self.axis.plot(x,y,color = cm(i_th/n_bin))
        self.axis.set_title("Gamma Distribution")
        self.FigureCanvas.draw()

        ### for obtaining mean,variance, and median
        self.MeanDisplay.setText(GetNDigit( a/b))
        self.VarianceDisplay.setText(GetNDigit(a/b**2))
        self.MedianDisplay.setText("not simple")

    def AddBeta(self):
        a = self.CurrentValues[0].value()
        b = self.CurrentValues[1].value()
        
        self.axis = self.Figure.add_subplot(1,1,1)
        be= beta(a = a,b= b)
        x = np.linspace(be.ppf(0.05),be.ppf(0.95),1000)
        if self.SelectType.currentText() == "Probability Density Function":
            y = be.pdf(x)
        elif self.SelectType.currentText() == "Cumulative Density Function":
            y = be.cdf(x)

        # add to graph
        cm = plt.get_cmap("rainbow")
        n_bin = self.binSpinBox.value()
        i_th = self.sld.value()
        
        self.axis.plot(x,y,color = cm(i_th/n_bin))
        self.axis.set_title("Beta Distribution")
        self.FigureCanvas.draw()

        ### for obtaining mean,variance, and median
        self.MeanDisplay.setText(GetNDigit( a/(a+b)))
        self.VarianceDisplay.setText(GetNDigit(a*b/(a+b)**2/(a+b+1)))
        self.MedianDisplay.setText(GetNDigit((a-1/3)/(a+b-2/3)))

    def AddPoisson(self):
        lam = self.CurrentValues[0].value()
        
        self.axis = self.Figure.add_subplot(1,1,1)
        pois = poisson(lam)
        x = [i for i in range(int(pois.ppf(0.05)),int(pois.ppf(0.95)+1))]
        if self.SelectType.currentText() == "Probability Mass Function":
            y = pois.pmf(x)
        elif self.SelectType.currentText() == "Cumulative Density Function":
            y = pois.cdf(x)

        # add to graph
        cm = plt.get_cmap("rainbow")
        n_bin = self.binSpinBox.value()
        i_th = self.sld.value()
        
        self.axis.plot(x,y,color = cm(i_th/n_bin))
        self.axis.set_title("Poisson Distribution")
        self.FigureCanvas.draw()

        ### for obtaining mean,variance, and median
        self.MeanDisplay.setText(GetNDigit( lam))
        self.VarianceDisplay.setText(GetNDigit(lam))
        if lam != 0:
            self.MedianDisplay.setText(GetNDigit(lam + 1/3 - 0.02/lam))
        else:
            self.MedianDisplay.setText("error")


    def SetFileList(self):
        # add names to File list
        self.names = ["Exponential","Normal","Poisson","Gamma","Beta"]
        
        for name in self.names:
            self.FileList.addItem(name)

        self.FileName = self.names[0]    


    def FileListChanged(self):
        # get file name opening 
        self.FileName = self.FileList.selectedItems()[0].text()

        if self.FileName == "Exponential":
            self.clearLayout(self.LineLayout)
            self.initExpoControl()        
            self.initExpoInfo()
            self.UpdateDist()

        if self.FileName == "Normal":
            self.clearLayout(self.LineLayout)
            self.initNormControl()
            self.initNormInfo()
            self.UpdateDist()

        if self.FileName == "Gamma":
            self.clearLayout(self.LineLayout)
            self.initGammaControl()
            self.initGammaInfo()
            self.UpdateDist()
            
        if self.FileName == "Beta":
            self.clearLayout(self.LineLayout)
            self.initBetaControl()
            self.initBetaInfo()
            self.UpdateDist()

        if self.FileName == "Poisson":
            self.clearLayout(self.LineLayout)
            self.initPoissonControl()
            self.initPoissonInfo()
            self.UpdateDist()

    #this function is for reference 
    def clearLayout(self, layout):
        if layout is not None:
            while layout.count():
                item = layout.takeAt(0)
                
                widget = item.widget()
                if widget is not None:
                    widget.deleteLater()
                else:
                    self.clearLayout(item.layout())

if __name__=="__main__":
    app = QtWidgets.QApplication(sys.argv)
    qapp = Application()
    qapp.show()
    sys.exit(app.exec_())

———-雑感(`・ω・´)———-
プログラム初心者の人にも使えるようにするためにはGUI化だけじゃなくて, 環境に依存しない .app か .exe に変換する必要があったよorz…
これに関しては, pyinstaller を用いれば可能だったけど容量が重くて起動が遅い.app, .exeになったよorz…
やっぱりがちなGUIを作るならcompiler型のプログラミング言語のjavaとか使わなきゃいけないのかーと痛感したよ…


コメント

タイトルとURLをコピーしました