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)二者之間存在父節點指向子節點的箭頭。
第八步完成