Rで解析:手描き風グラフを描画する「xkcd」パッケージ
発表資料や記事に図を添えるとき、整いすぎたグラフがかえって堅い印象を与え、読み手の関心を引きにくい場合があります。本パッケージは、「ggplot2」パッケージと同様の操作で、Webコミック「xkcd」を思わせる手描き風グラフのプロットが可能です。また、収録されている専用フォントを利用したテーマを適用することもできます。本パッケージにより、図の印象を和らげ、要点を伝える資料の作成が可能だと考えます。
パッケージバージョンは0.1.1。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。
パッケージのインストール
下記コマンドを実行してください。
# パッケージのインストール
install.packages("xkcd")
# パッケージの読み込み
# ggplot2は同時に読み込まれます
library("xkcd")手描き風の書体を利用するには、別途「xkcd」フォントをシステムにインストールします。フォントが見つからない場合は警告が表示され、既定の書体でプロットされます。下記、作業で「xkcd」フォントをシステムにインストールが可能です。
# xkcdフォントを作業フォルダにダウンロード
download.file(
"https://toledoem.github.io/img/xkcd.ttf",
destfile = "xkcd.ttf",
mode = "wb"
)
# フォントを開き、xkcdフォントをドラッグ&ドロップしてインストール
shell.exec("C:/Windows/Fonts")インストール後、Rを再起動し、下記コマンドの実行で利用可能です。
# 「extrafont」パッケージの読み込み
library("extrafont")
# インポート
font_import(
paths = file.path(Sys.getenv("LOCALAPPDATA"),
"Microsoft", "Windows", "Fonts"),
pattern = "xkcd",
prompt = FALSE
)
# 読み込み
loadfonts(device = "win")
Registering font with R using windowsFonts(): xkcdコマンド例
詳細はコメント、パッケージのヘルプを確認してください。
本パッケージのプロットは、線に乱数由来の揺らぎを加えたうえでベジエ曲線により平滑化する仕組みです。実行のたびに形が変わるため、同じ図を再現したい場合はset.seedコマンドを用いるか、後述のseed引数を指定します。
手描き風の軸のプロット:xkcdaxisコマンド
X軸とY軸を手描き風の線でプロットします。戻り値には座標系の設定とtheme_xkcdコマンドによるテーマが含まれるため、別途テーマを追加する必要はありません。
| オプション | 意味 | 初期値 |
|---|---|---|
| xrange | X軸の範囲 | なし |
| yrange | Y軸の範囲 | なし |
| … | geom_xkcdpathコマンドに渡すその他の引数 | なし |
# 架空の週別読書ページ数データを作成
dokusho <- data.frame(shu = 1:8,
pages = c(42, 65, 58, 90, 120, 105, 138, 160))
# X軸の範囲を取得
xhani <- range(dokusho$shu)
# Y軸の範囲を取得
yhani <- range(dokusho$pages)
# 揺らぎを再現できるように乱数の種を固定
set.seed(1234)
# 散布図に手描き風の軸を適用したプロット
ggplot() +
geom_point(aes(x = shu, y = pages), data = dokusho) +
xkcdaxis(xhani, yhani)
手描き風の長方形のプロット:xkcdrectコマンド
四辺の境界線に揺らぎを加えた長方形をプロットします。xmin、xmax、ymin、ymaxの4つの設定が必須です。塗りつぶし色と境界線は、fill、colour、linewidthで指定します。
| オプション | 意味 | 初期値 |
|---|---|---|
| data | このレイヤーで使用するデータセット | NULL |
| stat | このレイヤーで適用する統計変換 | “identity” |
| position | 位置の調整方法 | “identity” |
| … | layerコマンドに渡すその他の引数 | なし |
| borderxjitteramount | 境界線の水平方向の揺らぎ量 | 0.005 |
| borderyjitteramount | 境界線の垂直方向の揺らぎ量 | 0.005 |
| wobble | 2つの揺らぎ量に乗じる倍率、0で直線になる | 1 |
| seed | 境界線の揺らぎを再現するための整数 | NULL |
| na.rm | FALSEで欠損値を警告とともに除去するかの指定 | FALSE |
| show.legend | 凡例を表示するかの指定 | NA |
| inherit.aes | プロットからaesを継承するかの指定 | TRUE |
# 架空の年度別入部者数データを作成
bukatsu <- data.frame(nendo = 2021:2025,
ninzu = c(18, 24, 21, 30, 35))
# X軸の範囲を取得
xhani <- range(bukatsu$nendo)
# Y軸の範囲を取得
yhani <- range(bukatsu$ninzu)
# 手描き風の長方形と点を重ねたプロットを作成
# 揺らぎはseedで固定し、効果をわかりやすくするためwobbleで揺れ幅を1.5倍に設定
ggplot() +
xkcdrect(aes(xmin = nendo - 0.3,
xmax = nendo + 0.3,
ymin = ninzu - 2,
ymax = ninzu + 2),
data = bukatsu,
fill = "lightblue",
colour = "black",
linewidth = 1.2,
wobble = 1.5,
seed = 20250820) +
geom_point(aes(x = nendo, y = ninzu), data = bukatsu) +
xkcdaxis(xhani, yhani)
手描き風の線分と円のプロット:geom_xkcdpathコマンド
揺らぎを加えて平滑化した線分または円をプロットします。xとyに加えてxendとyendを与えると線分、diameterを与えると円としてプロットされます。colour、alpha、linewidth、linetypeの各aesにも対応しています。
| オプション | 意味 | 初期値 |
|---|---|---|
| data | データフレーム | NULL |
| stat | 適用する統計変換 | “identity” |
| position | 位置の調整方法 | “identity” |
| … | layerコマンドに渡すその他の引数 | なし |
| xjitteramount | 線分の水平方向の揺らぎ量、単位はデータの値 | 0.01 |
| yjitteramount | 線分の垂直方向の揺らぎ量、単位はデータの値 | 0.01 |
| wobble | 2つの揺らぎ量に乗じる倍率、0で直線になる | 1 |
| seed | 揺らぎを再現するための整数 | NULL |
| mask | TRUEで線の下に太い白色の線を重ねるかの指定 | TRUE |
| show.legend | 凡例を表示するかの指定 | NA |
| inherit.aes | プロットからaesを継承するかの指定 | TRUE |
# 架空の観測点をつなぐ線分の始点と終点データを作成
keiro <- data.frame(x = c(1, 2, 3, 4),
y = c(2, 4, 3, 5),
xend = c(2, 3, 4, 5),
yend = c(4, 3, 5, 4))
# 手描き風の線分をプロット
ggplot() +
geom_xkcdpath(aes(x = x, y = y, xend = xend, yend = yend),
data = keiro,
wobble = 3,
seed = 777)
diameterを設定すると円がプロットされます。
# 架空の3つの円の中心座標と直径データを作成
maru <- data.frame(x = c(1, 2.5, 4),
y = c(1, 2, 1.2),
diameter = c(1, 1.6, 0.8))
# 手描き風の円をプロット
# coord_fixedで縦横比を1に固定
ggplot() +
geom_xkcdpath(aes(x = x, y = y, diameter = diameter),
data = maru,
seed = 201) +
coord_fixed()
棒人間のプロット:xkcdmanコマンド
データのごとに1体の棒人間をプロットします。頭部の中心座標を表すxとy、全体の大きさを表すscale、X軸とY軸の縮尺比を表すratioxy、そして8か所の角度をラジアンで指定することが必要です。
| オプション | 意味 | 初期値 |
|---|---|---|
| data | このレイヤーで使用するデータセット | なし |
| seed | 棒人間の揺らぎを再現するための整数 | NULL |
| … | geom_xkcdpathコマンドに渡すその他の引数 | なし |
角度を指定するオプションは、背骨のangleofspine、右上腕のanglerighthumerus、左上腕のanglelefthumerus、右前腕のanglerightradius、左前腕のangleleftradius、右脚のanglerightleg、左脚のangleleftleg、首のangleofneckの8種類です。
# 架空の年度別ボランティア登録者数データを作成
touroku <- data.frame(nendo = 2020:2024,
ninzu = c(120, 148, 165, 190, 232))
# X軸の範囲を取得
xhani <- range(touroku$nendo)
# Y軸の範囲を取得
yhani <- range(touroku$ninzu)
# 棒人間がゆがまないようにX軸とY軸の縮尺比を算出
hiritsu <- diff(xhani) / diff(yhani)
# 2体の棒人間の位置と各関節の角度データを作成
ningen <- data.frame(x = c(2021, 2023),
y = c(215, 150),
scale = 15,
ratioxy = hiritsu,
angleofspine = -pi / 2,
anglerighthumerus = c(-pi / 6, -pi / 3),
anglelefthumerus = c(-pi / 2 - pi / 6, -pi / 2 - pi / 6),
anglerightradius = c(pi / 5, -pi / 5),
angleleftradius = c(pi / 5, -pi / 5),
anglerightleg = 3 * pi / 2 - pi / 12,
angleleftleg = 3 * pi / 2 + pi / 12,
angleofneck = -pi / 2)
# 棒人間のプロットに用いる対応付けを作成
taiou <- aes(x = x, y = y, scale = scale, ratioxy = ratioxy,
angleofspine = angleofspine,
anglerighthumerus = anglerighthumerus,
anglelefthumerus = anglelefthumerus,
anglerightradius = anglerightradius,
angleleftradius = angleleftradius,
anglerightleg = anglerightleg,
angleleftleg = angleleftleg,
angleofneck = angleofneck)
# 折れ線、手描き風の軸、棒人間を重ねたプロットを作成
ggplot() +
geom_line(aes(x = nendo, y = ninzu), data = touroku) +
xkcdaxis(xhani, yhani) +
xkcdman(taiou, ningen, seed = 100)
XKCDスタイルのテーマ設定:theme_xkcdコマンド
グリッド線や背景を取り除き、xkcdフォントを適用したテーマになります。xkcdフォントが見つからない場合は警告が表示され、既定の書体でプロットされます。
# 架空の月別ラジオ体操参加者数データを作成
taisou <- data.frame(tsuki = 1:6,
sanka = c(12, 15, 22, 28, 26, 34))
# 折れ線と点のプロットにXKCDスタイルのテーマを適用
ggplot(taisou, aes(x = tsuki, y = sanka)) +
geom_line() +
geom_point() +
theme_xkcd()
この記事が誰かの役に立ちますように。