Sankey diagraphとは、上のようなフローを表すグラフです。かなりの情報量を1つの図にまとめることができます。ただ、グラフを作成するにはデータ操作の技術が必要です。
今回は、R言語で、plotlyというインタラクティブなグラフを作成できるライブラリを使って作成します。上の図は、都合上画像ファイルを添付していますが、本来はインタラクティブなグラフになっています。一番下にインタラクティブなグラフがあります。
Plotlyのチュートリアルはこちらです。
早速作ってみます。
library(tidyverse)
library(plotly)
fig <- plot_ly(
type = "sankey",
orientation = "h", # v or h (vertical or horizon)
node = list( # バーの設定
label = c("A1", "A2","B1", "B2","C1", "C2"), #バーのラベル
color = c("lightpink", "lightpink",
"paleturquoise", "paleturquoise",
"lightslategray", "lightslategray"), #バーの色
pad = 40, # バーの相対的な長さの設定 1が最大、1以上で短く
thickness = 50, # バーの厚さ
line = list(
color = "grey", #バーの周りの線の色
width = 2 #バーの周りの線の厚み
)
),
link = list( # 移動を表す線の設定
source = c(0,1,0,2,3,3), # from
target = c(2,3,3,4,4,5), # to
value = c(8,4,2,8,4,2) # value
)
)
fig <- fig %>% layout(
title = "Basic Sankey Diagram",
font = list(
size = 10,
family = "serif",
color = "grey"
)
)
htmlwidgets::saveWidget(fig,"sankey.html")
これも都合上、画像を張っていますが本来はインタラクティブです。
私の環境では、なぜかplotlyがRstudio上に表示されません。htmlwidgets::saveWidget(fig,”sankey.html”)で、HTMLをカレントフォルダに保存します。その後、HTMLをウェブブラウザで開いてようやく見ることができます。
コード解説
label = c(“A1”, “A2″,”B1”, “B2″,”C1”, “C2”):バーのラベルです。ナンバリングが0から始まるリストと捉えて下さい。label[0] → “A1″。Rのナンバリングとずれていますが、javascript・pythonのナンバリングと同じです。
以下はセットです。縦にfrom – to – value の関係が成り立っています。valueは、バーの間をつなぐ帯の太さとなります。
source = c(0,1,0,2,3,3), # from
target = c(2,3,3,4,4,5), # to
value = c(8,4,2,8,4,2) , # value
1個めは、from label[0] to lable[2] value 8 ということになります。いいかえると、from “A1” to “B1” value 8です。次は、from label[1] to label[3] value 4です。つまり from “A2” to “B2” value 4です。
この形に合わせるためには、データの加工技術が必要です。
自分のデータでSankey diagraph
今回使うデータはこちらから作成しました。農林水産省の獣医事審議会の資料(獣医師の転職アンケート)の結果です。
https://www.maff.go.jp/j/council/zyuizi/keikaku/h30_2/attach/pdf/shiryo-4.pdf
準備するデータの形
何ページかあるのでデータを集計しました。preが転職前、postが転職後です。numberが何人いるかを示しています。
以下、プロットする前までのコードです。日本語フォントを使うための設定もしています。
library(tidyverse)
library(plotly)
windowsFonts(kozkagothic = windowsFont("KozGoPro-ExtraLight"))
df <- read.csv("jobchange.csv", encoding="UTF-8")
colnames(df) <- c("from","to","number")
df$factorfrom <- as.factor(df$from)
df$factorto <- as.factor(df$to)
df$factor_number_from <- as.numeric(df$factorfrom) - 1
df$factor_number_to <- as.numeric(df$factorto) - 1 + length(levels(df$factorfrom))
リスト番号でsourceとtarget (from to) を指定しなければならないので、上記のデータのままだと不適合です。そのため、変数を一回ファクターにして、ファクターの番号を保存する列を作ります。preとpostで同じ名前を使っているので、同じfactorの番号になります。それだとfrom list[1] to list[1]になってしまい、自分に帰ってしまうのでおかしくなります。都道府県から都道府県に転職した場合は、都道府県を2つのラベルとして設定し、list[1]からlist[5]のように、他のバーとして扱わないといけません。説明が難しい。。
以下が残りです。labelを、rep(levels(df$factorfrom),2)としていることに注意してください。from と toの2つ分です。
mycolors <- RColorBrewer::brewer.pal(length(levels(df$factorfrom)),"Pastel2")
mycolors <- rep(mycolors,2)
fig <- plot_ly(
type = "sankey",
orientation = "h", # v or h (vertical or horizon)
node = list( # バーの設定
label = rep(levels(df$factorfrom),2),
color = mycolors,
pad = 40, # バーの相対的な長さの設定 1が最大、1以上で短く
thickness = 50, # バーの厚さ
line = list(
color = "white", #バーの周りの線
width = 2 #バーの周りの線
)
),
link = list( # リンクの設定
source = df$factor_number_from, # from
target = df$factor_number_to, # to
value = df$number # value
)
)
fig <- fig %>% layout(
title = "獣医師の転職推移",
font = list(
size = 11,
family = "kozkagothic",
color = "grey"
)
)
htmlwidgets::saveWidget(fig, "vetjobchange.html")
一番上のコードは、バーの色が同じになるように工夫しているものです。
mycolors = c(“#909090”, “#123456”, ….. )