通靈
- 昨天,我把溪湖地區人口,依照戶籍登記地址繪製了直條圖。
- 但要把保安宮信仰推廣出去,是有不同訣竅的。
- 我們都知道,男男女女來到廟裡,祈求的事情大有不同;男人最多求發財,女人多求姻緣美滿和小孩身體健康。
目的
- 透過分析不同村里居住的男男女女,決定推廣宗教的模式。
預備知識
- 閱讀少量英文文件
- 今天要看更多的 JavaScript
-
箭頭函示
- ES6 中 Array 的內建方法
- JavaScript 中的科學記號
操作
先參考官方提供的範例
- 一樣是參考資料中的 D3 畫廊,找到分群直條圖,先欣賞一下 grouped-bar-chart
- 這張圖,根據美國的幾個州做分群,然後再繪製出各州內的不同年齡層人口數量。
- 所以在 GroupedBarChart 這個 function 接收一些資料。
生出對應的參數
-
x
-
x 即是 有哪些州 (分群)
- 我們的 x 則是 有哪些里 (分群)
- 等一下要吐出溪湖鎮 25 個里,暫時覺得容易好處理。
-
y
-
y 即是 人口除以一百萬 ... 還是人口
- 我們的 y 則是
男性
或 女性
- 跟範例不同的是,範例從
csv
讀入變數 states
;再把 states
根據不同年齡層,展開變成人口 (搞出一個新的屬性叫做 population)
- 等一下我們也要把溪湖各里人口格式轉換一下
- 原本一列資料是:??? 村里的 男性有 ??? 人、女性 ??? 人
- 之後要把一筆資料變成: ??? 村里、性別 ???、人數 ???
- 參考下面表格...
村名 |
鄰數 |
戶數 |
男性 |
女性 |
合計 |
光平里 |
14 |
458 |
723 |
705 |
1428 |
村名 |
性別 |
人數 |
光平里 |
男 |
723 |
光平里 |
女 |
705 |
到這邊就可以分成兩種做法:
(1) 如果你不太會寫 JavaScript 的話,那就直接重新生成一個 csv 檔,把 25 筆資料,展開變成 50 筆資料。
(2) 王爺公叫我參加鐵人賽,還是要用 JavaScript 來處理資料的啦。
-
z
-
z 即是 各州年齡層
- 我們畫的圖則是 各村里的性別
- 我們在上述展開資料步驟中已經順便處理好了。
看懂範例的 function
- 看一下變數分別是什麼 (改過的)
- 從原始資料讀進來的變數
- 原本範例寫成一行,醜醜的
stateages = ages.flatMap(age => states.map(d => ({state: d.name, age, population: d[age]}))) // pivot longer
stateages = ages.flatMap(
age => states.map(
d => ({
state: d.name,
age,
population: d[age]
})
)) // pivot longer
- 這個
d
原本就是傳進來 GroupedBarChart 的參數,我們的版本就是 states
- 等等
d
就是傳進 GroupedBarChart 的參數,我們的版本就是 xihu_population
- 最裡面的箭頭函示(上面片段 3 ~ 7 行)
- 把資料扔進去
- 回傳一個被大括弧包住的東西,就是 Object
- 新的 key 有
state
和 population
- 依序把值進去
-
state
是 州名
-
population
則是依照不同年齡層,填入該年齡層人口
- 我等一下會依照 各村里 的不同性別,填入該性別人數
- 如法炮製
village_gender_population = ages.flatMap(
性別 => xihu_population.map(
d => ({
村里: d.村名,
性別,
人數: d[性別]
})
))
- 小學生都會的造樣造句,改到一半發現,
ages
是什麼咧?
- 年齡層嘛,我們的版本是 男性 女性
- 範例用 slice 去切資料,我直接輸入就好。
- 最後變成
village_gender_population = gender.flatMap(
性別 => xihu_population.map(
d => ({
村名: d.村名,
性別,
人數: d[性別]
})
))
village_gender_population = gender.flatMap( 性別 => xihu_population.map(d => ({village: d.村名, 性別, 人數: d[性別]})))
- 貼上去之後,看看結果是不是一樣
畫圖
- 最麻煩的部分搞定了,最後一步填入 GroupedBarChart 參數的數值即可!!
gen_chart = GroupedBarChart(village_gender_population, {
x: d => d.村名,
y: d => d.人數,
z: d => d.性別,
yLabel: "↑ 信徒上限",
yDomain: [0, 3000],
zDomain: gender,
colors: d3.schemeSpectral[gender.length],
width,
height: 500
})
- 執行程式碼片段
完成繪圖
結論
- 原本要使用 Observable 繪製分群長條圖,但是找到的資料都是 Histogram “直方圖”;那個是用來描述資料數值群體分佈數量的東西,不同柱子之間的資料是連續性的。
- 使用
d3
製圖有較好的彈性。
參考資料