對plotTree的解釋


1.>>>a = 1/2/2
   >>>a

   >>>0.25

2.def plotMidText(cntrPt,parentPt,txtString):                                                    #在父子節點間填充文本信息
    xMid = (parentPt[0]-cntrPt[0])/2.0 + cntrPt[0]
    yMid = (parentPt[1]-cntrPt[1])/2.0 + cntrPt[1]
    createPlot.ax1.text(xMid,yMid,txtString)                                  #x和y的坐標軸  和填充內容
   
#為了方便理解這個函數我設定getNumLeafs=3   getDepth=2  
1.def plotTree(myTree,parentPt,nodeTxt):
2.      numLeafs = getNumLeafs(myTree)
3.      depth = getTreeDepth(myTree)                           #這個變量沒有用到
4.      firstStr = list(myTree.keys())[0]                       #得到字典的第一個鍵
5.      cntrPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW,                      
6.             plotTree.yOff)                                                                         #計算子節點的坐標(0.5,1.0)下面會改變喲
7.      plotMidText(cntrPt,parentPt,nodeTxt)
8.      plotNode(firstStr,cntrPt,parentPt,decisionNode)                                     
9.      secondDict = myTree[firstStr]                                                  #{0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}, 3: 'maybe'}
10.    plotTree.yOff = plotTree.yOff - 1.0/plotTree.totalD                        #到這里子系欸但坐標 (0.5,0.5)        
11.    for key in secondDict.keys():
12.         if type(secondDict[key]).__name__ == 'dict':
13.         plotTree(secondDict[key],cntrPt,str(key))                                #遞歸調用plotTree
14.    else:
15.         plotTree.xOff = plotTree.xOff + 1.0/plotTree.totalW
16.         plotNode(secondDict[key],(plotTree.xOff,plotTree.yOff),
17.                        cntrPt,leafNode)                                                    #調用上面的函數plotNode()
18.         plotMidText((plotTree.xOff,plotTree.yOff),cntrPt,str(key))
19. plotTree.yOff = plotTree.yOff + 1.0/plotTree.totalD
   
#為了方便理解這個函數我設定numLeafs=3   depth=2       
def createPlot(inTree):                                                    #畫圖函數
    fig = plt.figure(1,facecolor = 'white')
    fig.clf()                                                                            #清空畫布
    axprops = dict(xticks=[],yticks=[])                       #此參數表示坐標刻度,[]表示不顯示刻度,可以作為參數傳入,也可以用plt.xticks([1,3,4])單獨設置
    createPlot.ax1 = plt.subplot(111,frameon=False,**axprops)   
    plotTree.totalW = float(getNumLeafs(inTree))                         #寬度=3.0
    plotTree.totalD = float(getTreeDepth(inTree))                         #深度=2.0
    plotTree.xOff = -0.5/plotTree.totalW;plotTree.yOff = 1.0;        #得到兩個全局變量 x和y  (-1/6,1.0)
    plotTree(inTree,(0.5,1.0),'')                                                     #(0.5,1.0)頂層節點的坐標
    plt.show()       
   這段代碼個人覺得比較難理解(為了方便理解我們這里將寬度設置為3.0,深度設置為2.0)頂點坐標為(0.5,1.0)采取的myTree=

{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}

 

第一步 我們畫圖時候調用的是createPlot()這個函數,從函數我們得知   兩個全局變量(-1/6,1.0)即xOff,yOff  

第二步 我們看到該函數中存在plotTree(inTree,(0.5,1.0),'') 這段代碼,即調用了上面一個函數plotTree,經過計算我們得到子節點的第一個坐標(0.5,1.0)  即函數中第6行

第三步通過調用plotMidText和plotNode將頂點坐標內容(這里填充的內容是鍵的名稱)填充和設置格式,即頂點坐標(這里因為子節點和父節點是同一個點,所以頂點沒有指向的自己的箭頭)

第四步我們得到myTree第一個鍵對應的值並設為字典secondDict,第10行計算變量y的新值0.5,注意子節點此時還是(0.5,1.0)

第五步遍歷secondDict中的所有鍵,如果鍵對應的值是字典呢么遞歸調用plotTree注意里面的參數子節點(0.5,1.0)是panterPt的新參數,myTree對應的參數是secondDict[key]

第六步由給出myTree得知for循環中存在不是字典的值,呢么進入else:改變了xOff的值(經計算的為1/6)調用plotNode(secondDict[key],(1/6,0.5),(0.5,1.0),leafnode)即該處為葉子

第六步我們接着第五步遞歸調用,此時numLeafs變為2,depth變為1(這個depth沒用到可以忽略)我們還是取新字典的第一個鍵,計算子節點得到(2/3,0.5)

第七步同第三步驟,不過這里子節點和父節點不一致子節點(2/3,0.5)父節點(0.5,1.0)二者之間存在父節點指向子節點的箭頭。

第八步完成


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM