Rで解析:ggplot2に曲線やケーキの図形、凡例の角丸枠を足せる「ggfun」パッケージ
「ggfun」パッケージは、ggplot2で作ったプロットに、ベジェ曲線やなめらかな折れ線、ケーキや三角形の形をした点、角を丸めた凡例の枠、交互に色を付けた背景の帯といった、ggplot2だけでは用意されていない図形や装飾を足せるパッケージです。渡すのは、いつものggplot2と同じデータフレームと、作り終えたggplotオブジェクトです。ggplot2の拡張なので、ggplot2と一緒に読み込んで「+」でつなぐ形で使います。プロットの見た目をもう一段整えたい人や、発表資料で目を引く図を作りたい人に使えるのではないかと考えます。
パッケージバージョンは0.2.2。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。
<おすすめのRに関する書籍です>
パッケージのインストール
下記コマンドを実行してください。
# パッケージのインストール
install.packages("ggfun")
# パッケージの読み込み
library("ggfun")
ggfun v0.2.2 Learn more at https://yulab-smu.top/
# コマンド例の実行で必要なパッケージを読み込み
library("ggplot2")コマンド例
詳細はコメント、パッケージのヘルプを確認してください。例は、京都府内の直売所での宇治茶の販売、京野菜の重さと価格、丹波栗の重さ、菓子店の月ごとの売上、京都市の月平均気温などを題材にした架空のデータです。
ベジェ曲線は、始点と終点、その間の2つの制御点の計4点で形が決まる曲線です。曲線は始点と終点を通り、制御点の方へ引き寄せられます。エックススプライン曲線は、点と点の間をなめらかにつなぐ曲線で、各点にどれだけ寄せるかを-1から1の値で変えられます。
# 乱数を固定
set.seed(1)
# 直売所ごとの宇治茶の販売量(kg)と来客数
tea <- data.frame(
shop = c("宇治市", "和束町", "城陽市", "京田辺市", "木津川市", "亀岡市"),
kg = round(runif(6, 20, 80), 1),
visitors = round(runif(6, 100, 400))
)
# 京野菜1本あたりの重さ(g)と価格(円)
veg <- data.frame(
item = rep(c("九条ねぎ", "賀茂なす", "万願寺とうがらし"), each = 10),
price = c(rnorm(10, 300, 30), rnorm(10, 450, 40), rnorm(10, 380, 35)),
weight = c(rnorm(10, 120, 10), rnorm(10, 200, 15), rnorm(10, 90, 8))
)
# 乱数を固定
set.seed(42)
# 丹波と南丹市で収穫した栗1粒の重さ(g)
kuri <- data.frame(
area = rep(c("丹波", "南丹市"), each = 100),
g = c(rnorm(100, 25, 3), rnorm(100, 22, 3))
)
# 菓子店の月ごとの栗菓子の売上(万円)
cake <- data.frame(
month = 1:12,
sales = c(30, 35, 50, 80, 60, 40, 45, 55, 70, 90, 65, 100)
)
# 乱数を固定
set.seed(123)
# 京都市の月平均気温(℃)
temp <- data.frame(
month = 1:12,
t = round(c(
4.6, 5.4, 9.0, 14.6, 19.6, 23.4,
27.3, 28.5, 24.4, 18.3, 12.3, 6.9
) + rnorm(12, 0, 0.5), 1)
)文字の書体と色をまとめて変更:set_fontコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| p | ggplotオブジェクト | なし |
| family | フォントファミリー。NULLでプロットのものをそのまま使う | NULL |
| fontface | 書体。”bold”や”italic”、またはgridの数値コード1〜4 | NULL |
| size | 文字の大きさ。element_textと同じポイント単位 | NULL |
| color | 文字の色 | NULL |
# 直売所名を文字で置いたプロットを作成
p <- ggplot(tea, aes(x = kg, y = visitors)) +
geom_text(aes(label = shop), size = 5)
# 軸の文字と直売所名を明朝系の太字・深緑に変更
set_font(p, family = "serif", fontface = "bold", color = "darkgreen")軸の文字と直売所名を明朝系の太字・深緑に変更

凡例や見出し帯を角丸の枠にする:element_roundrectコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| fill | 塗りの色 | NULL |
| colour | 枠線の色 | NULL |
| linewidth | 枠線の太さ(mm) | NULL |
| linetype | 枠線の種類。0〜8の整数、”dashed”などの名前、または16進数の文字列 | NULL |
| color | colourの別名 | NULL |
| r | 角の丸みの半径。unitで指定する | grid::unit(0.1, “snpc”) |
| inherit.blank | TRUEで、親の要素がelement_blankのときにこの要素も消す | FALSE |
# 京野菜の重さと価格の散布図を作成
p2 <- ggplot(veg, aes(x = weight, y = price, color = item)) +
geom_point(size = 3)
# 凡例を灰色の破線の角丸枠で囲む
p2 + theme(legend.background = element_roundrect(color = "#808080", linetype = 2))
# 野菜ごとにパネルを分け、見出し帯を角丸にする
p2 + facet_grid(cols = vars(item)) +
theme(strip.background = element_roundrect(fill = "darkseagreen", color = NA, r = 0.15))凡例を灰色の破線の角丸枠で囲む

野菜ごとにパネルを分け、見出し帯を角丸にする

<おすすめのRに関する書籍です>
度数を数えてヒストグラムをプロット:geom_histコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| mapping | aes()で作る見た目の対応付け。inherit.aesがTRUEならプロット全体の対応付けと合わせて使う | NULL |
| data | このレイヤーで使うデータ。NULLでggplot()に渡したデータを使う | NULL |
| stat | データの集計方法 | “hist” |
| position | 重なりの調整方法。”dodge”で群ごとの棒を横に並べる | “identity” |
| breaks | 階級の数、またはそれを決める方法。hist()と同じ | “Sturges” |
| … | その他のオプション。colourやfillなどの固定の見た目を指定できる | なし |
| na.rm | TRUEで欠損値を警告なしに除く | FALSE |
| show.legend | 凡例に含めるか。NAで見た目の対応付けがあるときだけ含める | NA |
| inherit.aes | FALSEでプロット全体の見た目の対応付けを引き継がない | TRUE |
# 栗の重さのヒストグラムを作り、棒の上に度数を表示
ggplot(kuri, aes(x = g)) +
geom_hist(breaks = 15, color = "white", fill = "sienna") +
geom_text(stat = "hist", breaks = 15, vjust = -0.5, size = 4)
# 産地ごとに色を分け、棒を横に並べる
ggplot(kuri, aes(x = g, fill = area)) +
geom_hist(breaks = 15, position = "dodge")栗の重さのヒストグラムを作り、棒の上に度数を表示

産地ごとに色を分け、棒を横に並べる

4点からベジェ曲線をプロット:geom_bezierコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| mapping | aes()で作る見た目の対応付け | NULL |
| data | x、y、groupを持つデータフレーム | NULL |
| n | 曲線1本あたりの点の数 | 100 |
| stat | データの集計方法 | “identity” |
| position | 重なりの調整方法 | “identity” |
| na.rm | TRUEで欠損値を警告なしに除く | FALSE |
| show.legend | 凡例に含めるか | NA |
| inherit.aes | プロット全体の見た目の対応付けを引き継ぐか。groupごとに4点ちょうどが要るので初期値はFALSE | FALSE |
| … | その他のオプション | なし |
# 往路と復路それぞれの始点・制御点2つ・終点
route <- data.frame(
x = c(0, 1, 3, 4, 0, 1.5, 2.5, 4),
y = c(0, 2, 2, 0, 0, -1.5, -1.5, 0),
group = rep(c("往路", "復路"), each = 4)
)
# 往路と復路を色分けしてベジェ曲線をプロット
ggplot() +
geom_bezier(aes(x, y, group = group, color = group), data = route, linewidth = 1)往路と復路を色分けしてベジェ曲線をプロット

点をケーキの形でプロット:geom_cakeコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| mapping | aes()で作る見た目の対応付け | NULL |
| data | データ | NULL |
| … | その他のオプション | なし |
# 月ごとの栗菓子の売上をケーキの形でプロット
ggplot(cake, aes(x = month, y = sales)) +
geom_cake()月ごとの栗菓子の売上をケーキの形でプロット

点を三角形でプロット:geom_triangleコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| mapping | aes()で作る見た目の対応付け | NULL |
| data | データ | NULL |
| … | その他のオプション | なし |
# 月ごとの栗菓子の売上を三角形でプロット
ggplot(cake, aes(x = month, y = sales)) +
geom_triangle()月ごとの栗菓子の売上を三角形でプロット

<おすすめのRに関する書籍です>
点をなめらかな曲線でつなぐ:geom_xsplineコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| mapping | aes()で作る見た目の対応付け。inherit.aesがTRUEならプロット全体の対応付けと合わせて使う | NULL |
| data | このレイヤーで使うデータ。NULLでggplot()に渡したデータを使う | NULL |
| stat | データの集計方法 | “identity” |
| position | 重なりの調整方法 | “identity” |
| na.rm | TRUEで欠損値を警告なしに除く | FALSE |
| shape | 曲線を各点にどれだけ寄せるか。-1から1の数値ベクトル | 0 |
| open | TRUEで両端を開いた曲線、FALSEで閉じた形にする | TRUE |
| rep_ends | 開いた曲線で、最初と最後の点を重ねて曲線を端まで引くか。閉じた形では効かない | TRUE |
| show.legend | 凡例に含めるか。NAで見た目の対応付けがあるときだけ含める | NA |
| inherit.aes | FALSEでプロット全体の見た目の対応付けを引き継がない | TRUE |
| … | その他のオプション。colourやlinewidthなどの固定の見た目を指定できる | なし |
# 月平均気温の点を、各点に寄せた曲線(shape = 1)でつなぐ
ggplot(temp, aes(x = month, y = t)) +
geom_point() +
geom_xspline(color = "blue", linewidth = 1.2, shape = 1)
# 各点を通る曲線(shape = -1)でつなぐ
ggplot(temp, aes(x = month, y = t)) +
geom_point() +
geom_xspline(color = "blue", linewidth = 1.2, shape = -1)月平均気温の点を、各点に寄せた曲線(shape = 1)でつなぐ

各点を通る曲線(shape = -1)でつなぐ

背景を交互の色の帯にする:element_blindsコマンド
| オプション | 意味 | 初期値 |
|---|---|---|
| colour | 交互に塗る帯の色 | c(“white”, “grey60”) |
| axis | 帯を並べる軸。”y”または”x”。必ず指定する | なし |
| color | colourの別名 | NULL |
| inherit.blank | TRUEで、親の要素がelement_blankのときにこの要素も消す | FALSE |
# 京野菜ごとの価格の散布図で、横方向の背景を白と淡い緑の帯にする
ggplot(veg, aes(x = price, y = item)) +
geom_point(color = "darkgreen", size = 3) +
theme(panel.grid.major.y = element_blinds(color = c("white", "honeydew2"), axis = "y"))京野菜ごとの価格の散布図で、横方向の背景を白と淡い緑の帯にする

<おすすめのRに関する書籍です>
この記事が誰かの役に立ちますように。