はじめに
ハロー!プロジェクトの歴史を可視化しようシリーズ(仮)です。
この記事では、各グループ・ユニットのメンバー数の推移をバーチャートレースにします。
【他の記事】
【目次】
メンバー数の推移の可視化
ハロー!プロジェクトのグループ・ユニットのメンバー数の推移をバーチャートレースで可視化します。
次のパッケージを利用します。
# 利用パッケージ library(tidyverse) library(lubridate) library(gganimate)
この記事では、基本的にパッケージ名::関数名()
の記法を使うので、パッケージを読み込む必要はありません。
ただし、パイプ演算子%>%
を使うためmagrittr
と、作図コードがごちゃごちゃしないようにパッケージ名を省略するためggplot2
は読み込む必要があります。
データの読込
次のページのデータを利用します。
GitHub上のcsvデータをRから読み込めたらよかったのですがやり方が分からなかったので、ダウンロードしてローカルフォルダに保存しておきます。
保存先のフォルダパスを指定します。
# フォルダパスを指定 dir_path <- "data/HP_DB-main/"
ファイルの読み込み時にファイル名を結合する(ファイルパスにする)ので、末尾を/
にしておきます。
グループ・ユニットの情報を読み込みます。
# グループ一覧を読み込み group_df <- readr::read_csv( file = paste0(dir_path, "group.csv"), col_types = readr::cols( groupID = "i", groupName = "c", formDate = readr::col_date(format = "%Y/%m/%d"), dissolveDate = readr::col_date(format = "%Y/%m/%d"), isUnit = "l" ) ) %>% dplyr::arrange(groupID, formDate) # 昇順に並び替え group_df
## # A tibble: 60 x 5 ## groupID groupName formDate dissolveDate isUnit ## <int> <chr> <date> <date> <lgl> ## 1 1 モーニング娘。 1997-09-14 2013-12-31 FALSE ## 2 1 モーニング娘。 '14 2014-01-01 2014-12-31 FALSE ## 3 1 モーニング娘。 '15 2015-01-01 2015-12-31 FALSE ## 4 1 モーニング娘。 '16 2016-01-01 2016-12-31 FALSE ## 5 1 モーニング娘。 '17 2017-01-01 2017-12-31 FALSE ## 6 1 モーニング娘。 '18 2018-01-01 2018-12-31 FALSE ## 7 1 モーニング娘。 '19 2019-01-01 2019-12-31 FALSE ## 8 1 モーニング娘。 '20 2020-01-01 2020-12-31 FALSE ## 9 1 モーニング娘。 '21 2021-01-01 2021-12-31 FALSE ## 10 1 モーニング娘。 '22 2022-01-01 NA FALSE ## # ... with 50 more rows
group.csvは、グループID・グループ名・結成日・解散日・ユニットかどうかの5列のcsvファイルです。改名グループであれば結成日・解散日は改名日を表し、現在活動中であれば解散日が欠損値になります。
例えば、「モーニング娘。とモーニング娘。'14」「スマイレージとアンジュルム」「カントリー娘。とカントリー・ガールズ」は同一のグループとして共通のグループIDを持ちます。よって、groupID
列の値は重複し、groupName
列の値(文字列)は重複しません。
メンバーの加入日・卒業日の情報を読み込みます。
# 加入・卒業日一覧を読み込み join_df <- readr::read_csv( file = paste0(dir_path, "join.csv"), col_types = readr::cols( memberID = "i", groupID = "i", joinDate = readr::col_date(format = "%Y/%m/%d"), gradDate = readr::col_date(format = "%Y/%m/%d") ) ) %>% dplyr::arrange(joinDate, memberID, groupID) # 昇順に並び替え join_df
## # A tibble: 514 x 4 ## memberID groupID joinDate gradDate ## <int> <int> <date> <date> ## 1 1 1 1997-09-14 2001-04-15 ## 2 2 1 1997-09-14 2000-01-07 ## 3 3 1 1997-09-14 2005-01-30 ## 4 4 1 1997-09-14 2004-01-25 ## 5 5 1 1997-09-14 1999-04-18 ## 6 7 1 1998-05-03 2003-05-05 ## 7 8 1 1998-05-03 2005-04-14 ## 8 9 1 1998-05-03 2000-05-21 ## 9 2 2 1998-10-18 2000-01-07 ## 10 3 2 1998-10-18 2002-09-23 ## # ... with 504 more rows
join.csvは、メンバーID・グループID・加入日・卒業日の4列のcsvファイルです。現在活動中であれば卒業日が欠損値になります。
group.csvとjoin.csvのグループIDは対応しています。
この2つのデータを利用して、各グループの月ごとのメンバー数を集計します。
期間の指定
アニメーションとしてグラフ化する期間を指定して、データの受け皿となるデータフレームを作成します。
受け皿の作成
アニメーション化する期間を指定します。
# 期間を指定 date_from <- "1997-09-01" date_to <- "2022-05-07" #date_to <- lubridate::today()
開始日をdate_from
、終了日をdate_to
として期間を指定します。文字列でyyyy-mm-dd
やyyyy/mm/dd
、yyyymmdd
などと指定できます。現在の日付を使う場合は、today()
で設定します。
開始日を日付データに変換しておきます。
# 月初めのDate型に変換 date_from <- date_from %>% lubridate::as_date() %>% # Date型に変換 lubridate::floor_date(unit = "mon") # 月単位に切り捨て
後々使いやすくするために、文字列型で指定した開始日を、as_date()
でDate型に変換し、さらにfloor_date()
のunit
引数に"mon"
を指定して月初の日付にして(日にちを切り捨てて)おきます。
集計に利用する期間内の全ての月を持つベクトルを作成します。
# 月ベクトルを作成 date_vec <- seq( from = lubridate::as_date("1997-09-01"), # 一番古い月で固定 to = date_to %>% lubridate::as_date() %>% lubridate::floor_date(unit = "mon"), by = "mon" ) date_vec[1:5]
## [1] "1997-09-01" "1997-10-01" "1997-11-01" "1997-12-01" "1998-01-01"
seq()
で、第1引数from
から第2引数to
までのベクトルを作成します。第3引数by
に"mon"
を指定すると、1か月間隔のベクトルを作成します。
こちらも、引数に指定する値を月初のDate型に変換して使います。また集計の都合上、データベースの一番古い月(またはそれより前の月)にしておく必要があります。
「集計期間内の月」と「グループID」の全ての組み合わせ持つデータフレームを作成します。
# グループ数を取得 group_size <- max(group_df[["groupID"]]) # 月データフレームを作成 date_df <- tibble::tibble( date = rep(date_vec, each = group_size), groupID = rep(1:group_size, times = length(date_vec)) ) date_df
## # A tibble: 13,068 x 2 ## date groupID ## <date> <int> ## 1 1997-09-01 1 ## 2 1997-09-01 2 ## 3 1997-09-01 3 ## 4 1997-09-01 4 ## 5 1997-09-01 5 ## 6 1997-09-01 6 ## 7 1997-09-01 7 ## 8 1997-09-01 8 ## 9 1997-09-01 9 ## 10 1997-09-01 10 ## # ... with 13,058 more rows
月のベクトルdate_vec
とグループIDのベクトル1:group_size
の要素をそれぞれrep()
で複製します。
date_vec
は、each
引数にgroup_size
を指定して、各要素をグループ数ずつ複製します。1:group_size
は、times
引数にlength(date_vec)
を指定して、ベクトル全体を月と同じ数だけ繰り返して複製します。
このデータフレームにグループ名とメンバー数の情報を追加します。
演出用の処理
集計を行う前に、アニメーションの演出用のデータフレームを作成します。
改名グループの対応データ
各フレーム(各グラフ・各月)に応じてグループ名のラベルを変更するために、月とグループ名とを対応するデータフレームを作成します。
「期間内の全ての月」と「各月におけるグループ名」のデータフレームを作成します。
# 月・グループID・グループ名の対応表を作成 group_name_df <- group_df %>% dplyr::mutate( formDate = formDate %>% lubridate::floor_date(unit = "mon"), dissolveDate = dissolveDate %>% dplyr::if_else( condition = is.na(.), true = lubridate::today(), false = dissolveDate ) %>% # 現在活動中なら現在の日付 lubridate::floor_date(unit = "mon"), n = lubridate::interval(start = formDate, end = dissolveDate) %>% lubridate::time_length(unit = "mon") + 1 ) %>% # 月単位に切り捨てて月数をカウント tidyr::uncount(n) %>% # 月数に応じて行を複製 dplyr::group_by(groupName) %>% # 行番号用にグループ化 dplyr::mutate(idx = dplyr::row_number()) %>% # 行番号を割り当て dplyr::group_by(groupName, idx) %>% # 1か月刻みの値の作成用にグループ化 dplyr::mutate(date = seq(from = formDate, to = dissolveDate, by = "mon")[idx]) %>% # 複製した行を1か月刻みの値に変更 dplyr::group_by(date, groupID) %>% # 重複の除去用にグループ化 dplyr::slice_max(formDate) %>% # 重複する場合は新しい方を抽出 dplyr::ungroup() %>% # グループ化を解除 dplyr::select(date, groupID, groupName) %>% # 利用する列を選択 dplyr::arrange(date, groupID) # 昇順に並べ替え group_name_df
## # A tibble: 3,240 x 3 ## date groupID groupName ## <date> <int> <chr> ## 1 1997-09-01 1 モーニング娘。 ## 2 1997-10-01 1 モーニング娘。 ## 3 1997-11-01 1 モーニング娘。 ## 4 1997-12-01 1 モーニング娘。 ## 5 1998-01-01 1 モーニング娘。 ## 6 1998-02-01 1 モーニング娘。 ## 7 1998-03-01 1 モーニング娘。 ## 8 1998-04-01 1 モーニング娘。 ## 9 1998-05-01 1 モーニング娘。 ## 10 1998-06-01 1 モーニング娘。 ## # ... with 3,230 more rows
group_df
は、グループ名groupName
と結成日(改名日)formDate
・解散日(次の改名日)dissolveDate
の情報を持ちます。
そこで、グループ名ごとに、結成月から解散月(または現在の月)までの全ての月を作成します。
formDate, dissolveDate
列をfloor_date()
で結成月と解散月にします。ただし、解散前のグループであれば解散日がNA
なので、today()
で現在の日付に変更します。
結成月から解散月までの月数を、interval()
とtime_length()
を使って求めて、n
列とします。解散月 - 結成月
が求まるので+ 1
します。
uncount()
でn
列の値と同じ行数に複製します。
ここまでで、グループ名ごとに、その名前だった月数に応じて行(データ)が複製されました。続いて、1か月間隔の値を設定します。
複製した行にrow_number()
で行番号を割り当てて、idx
列とします。
結成月から解散月までの月ベクトルをseq()
で作成して、行番号に対応する要素を取り出して、date
列とします。
改名日が月の途中だと月(date
列の値)が重複するので、slice_max()
で新しい方の行(データ)を抽出します。
結成前月と解散月のデータ
バーの変化を強調するために、結成1か月前と解散月のデータ(メンバー数が0のデータ)を作成します。
グループごとの「結成1か月前と解散月」のデータフレームを作成します。
# 結成前月・解散月のデータを作成 member_0_df <- group_df %>% dplyr::group_by(groupID) %>% # 日付の再設定用にグループ化 dplyr::mutate(dissolveDate = dplyr::lead(dissolveDate, n = max(dplyr::n())-1)) %>% # 最後の行を1行目にズラす dplyr::slice_head(n = 1) %>% # 1行目を抽出 dplyr::ungroup() %>% # グループ化を解除 dplyr::mutate( formDate = formDate %>% lubridate::rollback() %>% # 結成1か月前に変更 lubridate::floor_date(unit = "mon"), dissolveDate = dissolveDate %>% lubridate::floor_date(unit = "mon") ) %>% # 月単位に切り捨て tidyr::pivot_longer( cols = c(formDate, dissolveDate), names_to = "date_type", values_to = "date" ) %>% # 結成前月・解散月を同じ列に変形 dplyr::select(date, groupID) %>% # 利用する列を選択 dplyr::filter(!is.na(date)) %>% # 現在活動中のグループの解散月を除去 tibble::add_column(member_n = 0) %>% # メンバー数(0人)を追加 dplyr::arrange(date, groupID) # 昇順に並び替え member_0_df
## # A tibble: 77 x 3 ## date groupID member_n ## <date> <int> <dbl> ## 1 1997-08-01 1 0 ## 2 1998-09-01 2 0 ## 3 1999-01-01 3 0 ## 4 1999-02-01 4 0 ## 5 1999-03-01 5 0 ## 6 1999-07-01 7 0 ## 7 1999-09-01 6 0 ## 8 2000-05-01 8 0 ## 9 2000-06-01 9 0 ## 10 2000-10-01 3 0 ## # ... with 67 more rows
group_df
のformDate, dissolveDate
列は、改名したグループだと、最初の行は「結成日・改名日」、途中の行は「改名日・改名日」、最後の行は「改名日・解散日」になります。
そこで、グループごとに、formDate
列の最初の値とdissolveDate
列の最後の値を取り出して、「結成日・解散日」にします。
dissolveDate
列の最後の行の値が最初の行に来るように、lead()
でズラします。ズラす行数の引数n
に、行数 - 1
の値を指定します。行数はn()
で得られますが行数分の値が返ってくるので、max()
で1つの値にして使います。
必要な値を最初の行にまとめられたので、slice_head()
で最初の行のみ取り出します。
続いて、次で作成する集計データと対応するようにデータフレームを変形します。
結成日と解散日をfloor_date()
で月初の値にします。その際に、rollback()
で結成月の1か月前にします。
pivot_longer()
で結成前月と解散月の列をまとめて、date
列とします。その際に、結成か解散かを表す列をdate_type
列としますが、この列は使いません。
結成前と解散後はメンバー数が0なので、値が全て0
のmember_n
列を作成します。
現在活動中のグループの解散月はNA
なので、is.na()
を使って取り除きます。
演出用の2つのデータフレームを用意できました。次の集計処理にそれぞれ利用します。
メンバー数の集計
メンバー数を集計して、多い順にランキングを付けます。
メンバー数の順位付け
各月における「メンバー数」と「順位」のデータフレームを作成します。
# メンバー数を集計してランク付け rank_df <- join_df %>% dplyr::mutate( joinDate = lubridate::floor_date(joinDate, unit = "mon"), gradDate = lubridate::floor_date(gradDate, unit = "mon") ) %>% # 月単位に切り捨て tidyr::pivot_longer( cols = c(joinDate, gradDate), names_to = "date_type", values_to = "date" ) %>% # 加入月・卒業月を同じ列に変形 dplyr::group_by(date, groupID, date_type) %>% # カウント用にグループ化 dplyr::count(name = "n") %>% # 変動数をカウント dplyr::ungroup() %>% # グループ化を解除 dplyr::left_join(date_df, ., by = c("date", "groupID")) %>% # 全期間に統合 tidyr::pivot_wider( names_from = date_type, values_from = n, values_fill = 0 ) %>% # 加入数・卒業数を別の列に変形 dplyr::select(date, groupID, join_n = joinDate, grad_n = gradDate) %>% # 利用する列を選択 dplyr::group_by(groupID) %>% # 在籍数の集計用にグループ化 dplyr::mutate(member_n = cumsum(join_n - grad_n)) %>% # 在籍数を集計 dplyr::ungroup() %>% # グループ化を解除 dplyr::filter(member_n > 0) %>% # 活動中のグループを抽出 dplyr::select(date, groupID, member_n) %>% # 利用する列を選択 dplyr::bind_rows(member_0_df) %>% # 在籍なし期間を結合 dplyr::arrange(date, groupID) %>% # ランク付け用に並べ替え dplyr::group_by(date) %>% # ランク付け用にグループ化 dplyr::mutate(ranking = dplyr::row_number(-member_n)) %>% # ランキング列を追加 dplyr::ungroup() %>% # グループ化を解除 dplyr::left_join(group_name_df, by = c("date", "groupID")) %>% # グループ名列を追加 dplyr::mutate( groupID = as.factor(groupID), groupName = tidyr::replace_na(groupName, replace = " ") ) %>% # 作図用に変換 dplyr::select(date, groupID, groupName, member_n, ranking) %>% # 列を並べ替え dplyr::filter(date >= date_from, date <= max(date_vec)) %>% # 期間内のデータを抽出 dplyr::arrange(date, ranking) # 昇順に並び替え rank_df
## # A tibble: 3,209 x 5 ## date groupID groupName member_n ranking ## <date> <fct> <chr> <dbl> <int> ## 1 1997-09-01 1 モーニング娘。 5 1 ## 2 1997-10-01 1 モーニング娘。 5 1 ## 3 1997-11-01 1 モーニング娘。 5 1 ## 4 1997-12-01 1 モーニング娘。 5 1 ## 5 1998-01-01 1 モーニング娘。 5 1 ## 6 1998-02-01 1 モーニング娘。 5 1 ## 7 1998-03-01 1 モーニング娘。 5 1 ## 8 1998-04-01 1 モーニング娘。 5 1 ## 9 1998-05-01 1 モーニング娘。 8 1 ## 10 1998-06-01 1 モーニング娘。 8 1 ## # ... with 3,199 more rows
join_df
には、各メンバーの加入日joinDate
と卒業日gradDate
の情報を持ちます。
joinDate, gradDate
列をfloor_date()
で加入月と卒業月にします。
pivot_longer()
で加入月と卒業月の列をまとめて、date
列とします。また、加入か卒業かを表す列をdate_type
列とします。
月ごとの加入数と卒業数をcount()
でカウントし、n
列とします。
ここまでは、変動があった月のデータのみです。left_join()
で「全ての月のデータdate_df
」に結合します。
変動数の列n
をpivot_wider()
で加入数と卒業数の列join_n, grad_n
に分割します。values_fill
引数に0
を指定すると欠損値(変動がなかった月の値)が0
になります。
加入数から卒業数を引いて、cumsum()
で累積和を計算して、各月におけるメンバー数member_n
列とします。
結成前や解散後は値が0
になるので、filter()
で削除します。
活動期間中のデータのみになりました。bind_rows()
で「結成前月と解散月のデータmember_0_df
」と結合します。
row_number()
でメンバー数に応じて順位を付けて、ranking
列とします。昇順に通し番号が割り当てられるので、-
を付けて大小関係を反転させます。
ここまでで、必要な値を集計できました。続いて、作図用の処理を行います。
left_join()
で「グループ名の情報group_name_df
」を結合します。
色分け用にグループIDを因子型に変換します。結成前月ではグループ名が欠損値になるので、空白(半角スペース)に置換します。
指定した描画期間の行(データ)を抽出します。
以上で、必要なデータを得られました。次は、作図を行います。
バーチャートレースの作成
メンバー数の推移を2種類のバーチャートレースで可視化します。バーチャートレースの作図については「【R】バーチャートレースのアニメーションの作図【gganimate】 - からっぽのしょこ」を参照してください。
フレームに関する値を指定します。
# 遷移フレーム数を指定 t <- 8 # 一時停止フレーム数を指定 s <- 2 # 1秒間に表示する月数を指定:(値が大きいと意図した通りにならない) mps <- 2.5 # フレーム数を取得 n <- length(unique(rank_df[["date"]])) n
## [1] 297
現月と次月のグラフを繋ぐアニメーションのフレーム数をt
として、整数を指定します。
各月のグラフで一時停止するフレーム数をs
として、整数を指定します。
基本となるフレーム数(月の数)をn
とします。
バーチャートレースを作成します。1つ目は、y軸を最大値で固定して描画します。
# バーチャートレースを作成:(y軸固定) anim <- ggplot(rank_df, aes(x = ranking, y = member_n, fill = groupID, color = groupID)) + geom_bar(stat = "identity", width = 0.9, alpha = 0.8) + # メンバー数のバー geom_text(aes(y = 0, label = paste(groupName, " ")), hjust = 1) + # グループ名のラベル geom_text(aes(y = 0, label = paste(" ", round(member_n))), hjust = 0, color = "white") + # メンバー数のラベル gganimate::transition_states(states = date, transition_length = t, state_length = s, wrap = FALSE) + # フレーム gganimate::ease_aes("cubic-in-out") + # アニメーションの緩急 theme( axis.title.y = element_blank(), # y軸のラベル axis.text.y = element_blank(), # y軸の目盛ラベル #panel.grid.major.x = element_line(color = "grey", size = 0.1), # x軸の主目盛線 panel.grid.major.y = element_blank(), # y軸の主目盛線 panel.grid.minor.x = element_blank(), # x軸の補助目盛線 panel.grid.minor.y = element_blank(), # y軸の補助目盛線 panel.border = element_blank(), # グラフ領域の枠線 #panel.background = element_blank(), # グラフ領域の背景 plot.title = element_text(color = "black", face = "bold", size = 20, hjust = 0.5), # 全体のタイトル plot.subtitle = element_text(color = "black", size = 15, hjust = 0.5), # 全体のサブタイトル plot.margin = margin(t = 10, r = 20, b = 10, l = 125, unit = "pt"), # 全体の余白 legend.position = "none" # 凡例の表示位置 ) + # 図の体裁 coord_flip(clip = "off", expand = FALSE) + # 軸の入れ変え scale_x_reverse(breaks = 1:max(rank_df[["ranking"]])) + # x軸を反転 labs(title = "ハロプログループのメンバー数の推移", subtitle = "{lubridate::year(closest_state)}年{lubridate::month(closest_state)}月", # ラベル y = "メンバー数", caption = "データ:「https://github.com/xxgentaroxx/HP_DB」") # ラベル
animate()
でgif画像を作成します。
# gif画像を作成 g <- gganimate::animate( plot = anim, nframes = n*(t+s), fps = (t+s)*mps, width = 900, height = 600 ) g
plot
引数にグラフ、nframes
引数にフレーム数、fps
引数に1秒当たりのフレーム数を指定します。
(ファイルサイズの上限は越えてないんだけどアップロードできなかったので完成例は省略します。)
anim_save()
でgif画像を保存します。
# gif画像を保存 gganimate::anim_save(filename = "output/MemberNum.gif", animation = g)
filename
引数にファイルパス("(保存する)フォルダ名/(作成する)ファイル名.gif"
)、animation
引数に作成したgif画像を指定します。
動画を作成する場合は、renderer
引数を指定します。
# 動画を作成と保存 m <- gganimate::animate( plot = anim, nframes = n*(t+s), fps = (t+s)*mps, width = 900, height = 600, renderer = gganimate::av_renderer("output/MemberNum.mp4") )
renderer
引数に、レンダリング方法に応じた関数を指定します。この例では、av_renderer()
を使います。
av_renderer()
のfile
引数に保存先のファイルパス("(保存する)フォルダ名/(作成する)ファイル名.mp4"
)を指定します。
ハロプログループ・ユニットのメンバー数の推移をアニメーションにしました!📊 #helloproject pic.twitter.com/2DWPw2ND5w
— しょこ📚 (@anemptyarchive) 2022年4月16日
(記事に動画を貼れないのでこれで代用します。)
2つ目は、グラフごとにy軸の範囲が変化します。
# バーチャートレースを作成:(y軸可変) anim <- ggplot(rank_df, aes(x = ranking, y = member_n, fill = groupID, color = groupID)) + geom_bar(stat = "identity", width = 0.9, alpha = 0.8) + # メンバー数のバー geom_text(aes(y = 0, label = paste(groupName, " ")), hjust = 1) + # グループ名のラベル geom_text(aes(label = paste(" ", round(member_n), "人")), hjust = 0) + # メンバー数のラベル gganimate::transition_states(states = date, transition_length = t, state_length = s, wrap = FALSE) + # フレーム gganimate::ease_aes("cubic-in-out") + # アニメーションの緩急 theme( axis.title.x = element_blank(), # x軸のラベル axis.title.y = element_blank(), # y軸のラベル axis.text.x = element_blank(), # x軸の目盛ラベル axis.text.y = element_blank(), # y軸の目盛ラベル axis.ticks.x = element_blank(), # x軸の目盛指示線 axis.ticks.y = element_blank(), # y軸の目盛指示線 panel.grid.major.x = element_line(color = "grey", size = 0.1), # x軸の主目盛線 panel.grid.major.y = element_blank(), # y軸の主目盛線 panel.grid.minor.x = element_blank(), # x軸の補助目盛線 panel.grid.minor.y = element_blank(), # y軸の補助目盛線 panel.border = element_blank(), # グラフ領域の枠線 panel.background = element_blank(), # グラフ領域の背景 plot.title = element_text(color = "black", face = "bold", size = 20, hjust = 0.5), # 全体のタイトル plot.subtitle = element_text(color = "black", size = 15, hjust = 0.5), # 全体のサブタイトル plot.margin = margin(t = 10, r = 40, b = 10, l = 130, unit = "pt"), # 全体の余白 legend.position = "none" # 凡例の表示位置 ) + # 図の体裁 coord_flip(clip = "off", expand = FALSE) + # 軸の入れ変え scale_x_reverse() + # x軸を反転 gganimate::view_follow(fixed_x = TRUE) + # 表示範囲の調整 labs(title = "ハロプログループのメンバー数の推移", subtitle = "{lubridate::year(closest_state)}年{lubridate::month(closest_state)}月", caption = "データ:「https://github.com/xxgentaroxx/HP_DB」") # ラベル
y軸(横軸)を可変にすると、月ごとに正規化されたようなグラフになります。
mp4ファイルを作成します。
よく見る演出Ver. #ハロプロ pic.twitter.com/dEm5DZ8hcB
— しょこ📚 (@anemptyarchive) 2022年4月16日
月を指定して作図
最後に、指定した月のメンバー数のグラフを作成します。
# 月を指定 date_val <- "2021-05-01" # 棒グラフを作成 rank_df %>% dplyr::filter(date == lubridate::as_date(date_val)) %>% ggplot(aes(x = ranking, y = member_n, fill = groupID, color = groupID)) + geom_bar(stat = "identity", width = 0.9, alpha = 0.8) + # メンバー数のバー geom_text(aes(y = 0, label = paste(groupName, " ")), hjust = 1) + # グループ名のラベル geom_text(aes(y = 0, label = paste(" ", round(member_n), "人")), hjust = 0, color = "white") + # メンバー数のラベル theme( axis.title.y = element_blank(), # y軸のラベル axis.text.y = element_blank(), # y軸の目盛ラベル #panel.grid.major.x = element_line(color = "grey", size = 0.1), # x軸の主目盛線 panel.grid.major.y = element_blank(), # y軸の主目盛線 panel.grid.minor.x = element_blank(), # x軸の補助目盛線 panel.grid.minor.y = element_blank(), # y軸の補助目盛線 panel.border = element_blank(), # グラフ領域の枠線 #panel.background = element_blank(), # グラフ領域の背景 plot.title = element_text(color = "black", face = "bold", size = 20, hjust = 0.5), # 全体のタイトル plot.subtitle = element_text(color = "black", size = 15, hjust = 0.5), # 全体のサブタイトル plot.margin = margin(t = 10, r = 20, b = 10, l = 125, unit = "pt"), # 全体の余白 legend.position = "none" # 凡例の表示位置 ) + # 図の体裁 coord_flip(clip = "off", expand = FALSE) + # 軸の入れ変え scale_x_reverse(breaks = 1:max(rank_df[["ranking"]])) + # x軸を反転 labs(title = "ハロプログループのメンバー数", subtitle = paste0(lubridate::year(date_val), "年", lubridate::month(date_val), "月時点"), # ラベル y = "メンバー数", caption = "データ:「https://github.com/xxgentaroxx/HP_DB」") # ラベル
以上で、メンバー数の推移を可視化できました。
おわりに
コードがごちゃごちゃしててすぐに忘れそうなので自分用のメモです。purrr
を使えるともう少し上手く処理できるのかもしれませんが、今の私ではこれが限界です。℃-uteの℃が豆腐化してるのもなんとかしたいけど力尽きました…
それと、はてなブログにいい感じに(少しファイルサイズの大きい)gifファイルとmp4ファイルを貼る方法がないものか…YouTube始めるかぁ。
データベースの整備に感謝しつつ、他にもいくつかやっていきます。
さて、2022年5月7日は元モーニング娘。の佐藤優樹さんのお誕生日です!おめでとうございます!
私はこの曲をきっかけにまーちゃんとモーニング娘。とハロプロにハマりました。出会えて良かった。