iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0

通靈

  • 昨天,我把溪湖地區人口,依照戶籍登記地址繪製了直條圖。
  • 但要把保安宮信仰推廣出去,是有不同訣竅的。
  • 我們都知道,男男女女來到廟裡,祈求的事情大有不同;男人最多求發財,女人多求姻緣美滿和小孩身體健康。

目的

  • 透過分析不同村里居住的男男女女,決定推廣宗教的模式。

預備知識

  • 閱讀少量英文文件
  • 今天要看更多的 JavaScript
    • 箭頭函示
      • 這個寫法很潮很帥
    • ES6 中 Array 的內建方法
    • JavaScript 中的科學記號
      • 1e6 == 1 後面多 6個0 ... 一百萬

操作

先參考官方提供的範例

  • 一樣是參考資料中的 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 有 statepopulation
      • 依序把值進去
        • 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
})
  • 執行程式碼片段

完成繪圖

結論

  1. 原本要使用 Observable 繪製分群長條圖,但是找到的資料都是 Histogram “直方圖”;那個是用來描述資料數值群體分佈數量的東西,不同柱子之間的資料是連續性的。
  2. 使用 d3 製圖有較好的彈性。

參考資料


上一篇
【Day 2】 簡單的 “D3” 直條圖
下一篇
【Day 4】 簡單的折線圖
系列文
適用於傳產從業人員的實用報表製圖術30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言