樹狀圖在某些特點上跟泡泡圖的類似,都可以提供不只1個維度的資訊,並透過形狀大小、顏色來呈現。但是比較不同的地方是樹狀圖有層級的概念,可以用來呈現階層式資料。例如將全臺灣當作第一層,縣市當做第二層(分支),再下一層則是縣市人口年齡組成。
在這基本概念下利用python的Plotly套件來繪製堆疊區域圖。這次以2013-2016年國民營養健康調查報告書中的數據為例。
以下針對2013-2016年國民營養健康調查做簡單的介紹:
² 目的:隨時代改變人們飲食習慣也隨之改變,為了對國人的營養健康狀況有所了解,從1980年開始委託衛生署食品衛生處、衛生署食品藥物管理局定期辦理全國性營養健康調查,2013年起改由衛生福利部國民健康署定期辦理。2013-2016年的調查為第五次的國民營養調查。
² 調查對象:所有居住在臺灣本島及澎湖設有戶籍的人口,依據縣市人口比例分層集束抽樣,進行家戶田野調查。
² 問卷:除人口社經等基本資料的收集外,包含24小時飲食回顧、飲食頻率、疾病史、營養知識態度與行為、活動量等相關問卷以及身體健康檢查資料。
2013-2016年總計問卷完訪人數有11,072人,體檢人數為9746人。
十大死因中心血管疾病常常榜上有名,可見一直是國人重要的死亡原因之一,但因疾病病徵較不明顯,相較於癌症來說反而容易受到忽略,但實則不可輕忽,應即早預防與控制,其中抽煙、高血壓、糖尿病、高血脂等都是心血管疾病的危險因子,本次以高膽固醇數據做示範,了解2013-2015年不同年齡層高膽固醇盛行的情況。
操作步驟
1.選定主題,準備素材
以2013-2016年國民營養健康調查中高膽固醇盛行率為例(衛生福利部國民健康署公告的資料),了解不同年齡層收到的檢體中,高膽固醇盛行的形況。開始執行前,尚未安裝plotly者需要先安裝幾個套件plotly、numpy以及squarify,在Window環境下,開起命令提示字元,輸入pip install plotly,其他套件也以相同的方式匯入,安裝完成後,就可進入繪圖步驟。
用Squarify這個套件來計算圖形區域的分割,一個大正方形的區域依照比例分割成幾個不同大小的矩形,並運算每個放入的矩形的長寬比需盡量接近1(正方形),當矩形長寬比違反這個情況時,會調整矩行放入的位置至最適情況。
2.確認繪圖需要用到的參數:
因為目前plotly的繪圖沒有辦法像tableau那麼方便,如果要到2層的樹狀結構圖(treemap),就必須藉由半手動的方式達成,第一層變量為年齡分層的採檢人數,方塊的大小由檢體採檢人數多寡決定,這部份可由套件直接計算,第二層為年齡分層的盛行率,盛行率高低的由顏色深淺表示,這部份就只能夠過手動設定調整。
3.繪製樹狀圖treemap
這次採用各分層在同一圖層做建構,省去合併處理的語法。
import plotly.plotly as py import plotly.graph_objs as go import numpy as np import squarify #設定x,y軸的起始值 x = 0. y = 0. #設定圖的大小 width = 100. height = 100. normed = squarify.normalize_sizes(df["pop"], width, height) #df["pop"]為帶入的數據 rects = squarify.squarify(normed, x, y, width, height) color_brewer=df["color"].tolist() #色彩於讀入的表格中已設好,將之轉為串列 z=np.random.randint(4, 30, size=20) #設定色標的範圍 colorscale=[[0.0, 'rgb(169,233,207)'], [0.5, 'rgb(81,211,158)'],[1.0, 'rgb(37,147,102)']] #設定色標的色彩 shapes = [] annotations = [] counter = 0 for r in rects: shapes.append( dict( type = 'rect', x0 = r['x'], y0 = r['y'], x1 = r['x']+r['dx'], y1 = r['y']+r['dy'], line = dict( width = 1, color="white"), #設定treemap框線的粗細及色彩 fillcolor = color_brewer[counter], #設定填入的色彩 ) ) annotations.append( dict( x = r['x']+(r['dx']/2), y = r['y']+(r['dy']/2), text = "年齡"+df["age"][counter]+"\n"+"人數:"+str(value[counter])+"\n"+"盛行率:"+str(df["value"][counter])+"%", #設定框內文字敘述 font=dict(color="black",size=14,family='微軟正黑體'), #設定框內字體及大小 showarrow = False)) counter = counter + 1 if counter >= len(color_brewer): counter = 0 print(shapes) # For hover text trace0 = go.Scatter( x = [ r['x']+(r['dx']/2) for r in rects], y = [ r['y']+(r['dy']/2) for r in rects], text = [ str(v) for v in value], mode = 'markers', marker=dict(color=z,colorscale=colorscale, size=14, colorbar=dict(thickness=20)) #將已設定好的色標參數帶入 ) layout = dict( height=700, width=700, xaxis=dict(showgrid=False,zeroline=False,showticklabels=False), yaxis=dict(showgrid=False,zeroline=False,showticklabels=False), shapes=shapes, annotations=annotations, hovermode='closest' ) figure = dict(data=[trace0], layout=layout) py.iplot(figure, filename='squarify-treemap')
您好,謝謝您慷慨地分享統計相關資訊。
回覆刪除因剛入門統計與程式語言,有很多不了解的地方,不知道是不是能向您請教呢?
謝謝您喔!