樹狀圖在某些特點上跟泡泡圖的類似,都可以提供不只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')
您好,謝謝您慷慨地分享統計相關資訊。
回覆刪除因剛入門統計與程式語言,有很多不了解的地方,不知道是不是能向您請教呢?
謝謝您喔!