本文へスキップ
からだにいいもの

Rのトピックスを中心に『まだ、まだ、知らない、役に立つ情報?』を発信します。

Rで解析:ggplot2に曲線やケーキの図形、凡例の角丸枠を足せる「ggfun」パッケージ

「ggfun」パッケージは、ggplot2で作ったプロットに、ベジェ曲線やなめらかな折れ線、ケーキや三角形の形をした点、角を丸めた凡例の枠、交互に色を付けた背景の帯といった、ggplot2だけでは用意されていない図形や装飾を足せるパッケージです。渡すのは、いつものggplot2と同じデータフレームと、作り終えたggplotオブジェクトです。ggplot2の拡張なので、ggplot2と一緒に読み込んで「+」でつなぐ形で使います。プロットの見た目をもう一段整えたい人や、発表資料で目を引く図を作りたい人に使えるのではないかと考えます。

パッケージバージョンは0.2.2。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。

パッケージのインストール

下記コマンドを実行してください。

# パッケージのインストール
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コマンド

オプション意味初期値
pggplotオブジェクトなし
familyフォントファミリー。NULLでプロットのものをそのまま使うNULL
fontface書体。”bold”や”italic”、またはgridの数値コード1〜4NULL
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
colorcolourの別名NULL
r角の丸みの半径。unitで指定するgrid::unit(0.1, “snpc”)
inherit.blankTRUEで、親の要素が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))

凡例を灰色の破線の角丸枠で囲む

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

度数を数えてヒストグラムをプロット:geom_histコマンド

オプション意味初期値
mappingaes()で作る見た目の対応付け。inherit.aesがTRUEならプロット全体の対応付けと合わせて使うNULL
dataこのレイヤーで使うデータ。NULLでggplot()に渡したデータを使うNULL
statデータの集計方法“hist”
position重なりの調整方法。”dodge”で群ごとの棒を横に並べる“identity”
breaks階級の数、またはそれを決める方法。hist()と同じ“Sturges”
…その他のオプション。colourやfillなどの固定の見た目を指定できるなし
na.rmTRUEで欠損値を警告なしに除くFALSE
show.legend凡例に含めるか。NAで見た目の対応付けがあるときだけ含めるNA
inherit.aesFALSEでプロット全体の見た目の対応付けを引き継がない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コマンド

オプション意味初期値
mappingaes()で作る見た目の対応付けNULL
datax、y、groupを持つデータフレームNULL
n曲線1本あたりの点の数100
statデータの集計方法“identity”
position重なりの調整方法“identity”
na.rmTRUEで欠損値を警告なしに除くFALSE
show.legend凡例に含めるかNA
inherit.aesプロット全体の見た目の対応付けを引き継ぐか。groupごとに4点ちょうどが要るので初期値はFALSEFALSE
…その他のオプションなし
# 往路と復路それぞれの始点・制御点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コマンド

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

月ごとの栗菓子の売上をケーキの形でプロット

点を三角形でプロット:geom_triangleコマンド

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

月ごとの栗菓子の売上を三角形でプロット

点をなめらかな曲線でつなぐ:geom_xsplineコマンド

オプション意味初期値
mappingaes()で作る見た目の対応付け。inherit.aesがTRUEならプロット全体の対応付けと合わせて使うNULL
dataこのレイヤーで使うデータ。NULLでggplot()に渡したデータを使うNULL
statデータの集計方法“identity”
position重なりの調整方法“identity”
na.rmTRUEで欠損値を警告なしに除くFALSE
shape曲線を各点にどれだけ寄せるか。-1から1の数値ベクトル0
openTRUEで両端を開いた曲線、FALSEで閉じた形にするTRUE
rep_ends開いた曲線で、最初と最後の点を重ねて曲線を端まで引くか。閉じた形では効かないTRUE
show.legend凡例に含めるか。NAで見た目の対応付けがあるときだけ含めるNA
inherit.aesFALSEでプロット全体の見た目の対応付けを引き継がない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”。必ず指定するなし
colorcolourの別名NULL
inherit.blankTRUEで、親の要素が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"))

京野菜ごとの価格の散布図で、横方向の背景を白と淡い緑の帯にする


この記事が誰かの役に立ちますように。

スポンサーリンク
価格および配送状況は変更される場合があります。購入時は商品ページをご確認ください。
当サイトに表示されている商品情報はAmazonから提供されたものであり、更新または削除される場合があります。
karada-goodはAmazonアソシエイトとして、適格販売により収入を得ています。