5. plot_FUNについて

Note

自身でABMを作成する際に、stateactive stateの次の手順として作ることをお勧めするのが描画に関するフィールドカテゴリー(plot_FUN)です。plot_FUNを早い段階でつくっておくことで、自身のstateがどのような状況か、更新を行ったあとstateが適切に変化しているのかを把握しやすくなります。この章では、plot_FUNの作成、作成上の注意について解説します。

5.1 plot_FUNの作り方

(1) baseパッケージを用いたplot

plot_FUNは、Plot()で関数をくくったうえで、Gameオブジェクトに格納することで実装できます。以下は、100人のエージェントの正規分布に従った得点xのヒストグラムをプロットするplot_FUNを作成する例です。なお、ABMにおいて、プロットしている時間がどの時点なのかは特に重要なことが多いため、plot_FUNを作る際には時点を同時に表記できるように関数を組むことがお勧めします。当該時点は$timeでアクセスできますので、関数上はself$timeと参照させるようにすればよいです。

library(rABM)
# xを作成し、Gameに格納する
n <- 100
x <- rnorm(n = n)
G <- Game(State(x))

# ヒストグラムを出力する関数plot_xを作成する
plot_x <- function(){
  hist(self$x, 
       main = paste("time =", self$time),
       xlab = "x")
}

# Gに追加する
add_field(G, Plot(plot_x))

プリントすることで、Gameオブジェクトに適切に格納されていることをいったん確認します。末尾のメタデータ欄にplot_FUN: plot_xという表示が入っていることが分かります。

G
<Game>
$x(state)
  [1]  0.378473849  0.097873167 -0.342488064 -0.175056328 -1.054047941
  [6]  0.425224134 -0.575651866 -0.628467056 -0.536051587 -0.602213661
 [11] -0.515536695  0.187918477  1.540957498 -0.676046146 -0.568634605
 [16]  0.101851729  0.999183150 -0.530184170 -1.647724912  1.550487013
 [21] -0.739287529  0.942165610  0.012674254  0.867070679 -0.122140260
 [26] -0.110102313 -0.181250555  0.997137498  0.316022328 -1.145035170
  ---- (truncated) ----

$plot_x(plot_FUN)
function () 
{
    hist(self$x, main = paste("time =", self$time), xlab = "x")
}

------------------- 
time         : 1 
n of logs    : 0 
n of notes   : 0 
n of fields  : 2 
 state       : x
 plot_FUN    : plot_x
------------------- 
*Some fields are truncated. Increase 'max_lines' to display more.

さっそく実際に図示してみましょう。適切に図示できてることが分かります。

G$plot_x()

(2) ggplot2パッケージを用いたプロット

なお、ここではbaseパッケージのプロット機能を用いていますが、ggplotを使用することももちろんできます。ただしggplotはbaseパッケージよりも描画に時間がかかることが多いことに留意しておいてください。また、関数末尾において、明示的にggplotのオブジェクトをprint()で呼び出す必要**があることに注意してください。

# ggplot2を読み込む
library(ggplot2)
Warning: package 'ggplot2' was built under R version 4.5.2
# ggplot2を用いた図示用の関数を作成する
plot_x_ggp <- function(){
  # ggplotで扱えるようdata.frameに変換する
  df <- data.frame(x = self$x)
  
  # plot用の設定をgに付加する
  g <- ggplot(aes(x = x), data = df) + geom_histogram() + 
    ggtitle(paste("time =", self$time))
  
  # 描画には明示的にprintで呼び出す
  print(g)
  }

# Gに格納する
add_field(G, Plot(plot_x_ggp))

実際に図示してみます。

# 図示する
G$plot_x_ggp()
`stat_bin()` using `bins = 30`. Pick better value `binwidth`.

(3) 定義されたすべてのplotを順にみる

Gameオブジェクトに定義されたすべてのplot_FUNは、plot()Gameオブジェクトを呼び出すことによって、順に呼び出すことができます。以下の関数を実行すると、インテラクティブモードになり、<ENTER>を推すたびに、定義されているplot_FUNが順に呼び出されます(出力省略)。

plot(G)

個別に呼び出すことも可能です。その場合には、nameで呼び出したいplot_FUNのフィールド名を指定します。

plot(G, name = c("plot_x"))

使っているエディターによっては、plotはジェネリックのため引数候補を見にくい場合があるかもしれません。その場合にはplot_Game関数を用いていください。この関数は、plot関数のラッパーとなっており、結果的に同じ出力がなされます。

5.2 logをプロットする

Gameオブジェクトに保存されているlogをプロットしたい場合には、plot関数の引数のlog指定をしてください。logはインデックス(i.e., 1, 2, 3,…)もしくは、時点の文字列(i.e., "t1","t2")のいずれかで指定できます。

# 例示のための簡単なxの更新関数を作成する。
update_x <- function(){self$x <- self$x + rnorm(n = 100)}

# Gameに付加する
add_field(G, Act(update_x))

# 3回更新する
G2 <- run_Game(G, plan = "update_x", times = 3)
# インデックスで指定してlogをプロットする
plot(G2, name = "plot_x", log = 3)
printing: 1/1

# 時点を文字列でしてlogをプロットする
plot(G2, name = "plot_x", log = "t3")
printing: 1/1

# 複数の時点を表示する
plot(G2, name = "plot_x", log = c(1,3))
printing: 1/2

printing: 2/2