ggplot2::theme()
等の引数を個別に指定することで容易に変更することができます.
しかし, 一つの文字列内で複数のフォントを混在させるのは,
かなりの手間です. 例えば, stack
overflowに解決策の一例がありますが, 文字列が長くなるのと,
htmlの知識が必要になります.mixfonts()
を作成しました.
library(frabento) # このパッケージ
library(ggplot2) # 作図
library(ggtext) # element_markdown()などを使うため
library(patchwork) # ggplotを簡単, キレイにレイアウト
library(ragg) # マルチバイト文字のfallback
frabento::register_all_fonts() # system下のfontを登録. fontregistererより移植
mixfonts()
では,
デフォルトのASCII文字フォントをArial,
マルチバイト文字フォントをMS Gothicにしています.
# ベースのthemeをsetしておく
theme_set(theme_linedraw(base_family = "MS Gothic") +
theme(aspect.ratio = 1/1)) # アスペクト(縦横)比
# 仮想データ作成
dat <- data.frame(cpue = rnorm(n = 30, mean = 500, sd = 35),
year = seq(1990, length.out = 30, by = 1))
# まずはmixfontsを使わない
g <- ggplot(data = dat, aes(x = year, y = cpue)) +
geom_path() + geom_point() +
labs(x = "年", y = "CPUE (/1000網)") +
theme(axis.title.y = element_text(color = "blue"))
# mixfontsを使うと
gm <- g + labs(y = mixfonts("CPUE (/1000網)")) +
theme(axis.title.y = ggtext::element_markdown(angle = 90, color = "blue"))
# use patchwork
g | gm
文字列の折り返しや上付き (superscript), 下付き (subscript)
にも対応してます.
上付き・下付きいずれの場合も, 添字部分は中括弧 {}
で囲んでください. 次のコードを参照.
# 折り返したい位置に改行記号 `\n` を挿入
gm4 <- gm + labs(y = mixfonts("A海区における\n大中型まき網漁業の\nCPUE (/1000網)"))
# 上付き, 下付き
gm5 <- gm + labs(y = mixfonts("A海区における産卵量\n(eggs_{a} 10^{12})",
mbyte = "HGSSoeiKakugothicUB"))
# mixfont() を使わなくても折り返しはできる (フォントの混在は不可).
g_ <- g + labs(y = "A海区における\n大中型まき網漁業の\nCPUE (/1000網)")
# フォントをASCII (シングルバイト文字) に変更すると日本語部分が豆腐化※.
# フォントが上書きされる.
# ※ GitHub Pages上では日本語部分が補完されて表示されているかもしれません.
g__ <- g_ + theme(axis.title.y = element_text(family = "Arial"))
# patchwork
gm4 + gm5 + g_ + g__ + plot_layout(ncol = 2, byrow = TRUE)
# 仮想データ
d2 <- data.frame(cpue = c(rnorm(n = 30, mean = 300, sd = 25),
rnorm(n = 30, mean = 500, sd = 35)),
year = rep(seq(1990, length.out = 30, by = 1), times = 2),
age = rep(c("0歳魚", "1歳魚+"), each = 30))
pbase <- ggplot(data = d2, aes(x = year, y = cpue, group = age)) +
geom_path(aes(color = age))
p0 <- pbase +
theme(legend.text = element_text(color = "blue")) +
labs(title = "混在できない")
# mixfonts()を使う (値の指定が必要 => 値を変更できる利点も)
pm1 <- pbase +
scale_color_discrete(labels = mixfonts(c("0歳魚", "1歳魚以上"))) +
theme(legend.text = ggtext::element_markdown(color = "blue")) +
labs(title = "混在 by mixfonts()")
# label_mixfonts()を使う (関数を返すので値の指定は不要. dataの値は変更できない)
pm2 <- pbase +
scale_color_discrete(labels = label_mixfonts()) +
theme(legend.text = ggtext::element_markdown(color = "blue")) +
labs(title = "混在 by label_mixfonts()")
# patchwork
p0 + plot_spacer() + pm1 + pm2 + plot_layout(ncol = 2, byrow = TRUE)
パネル内テキストは元のデータ (ラベル部分)
をmixfonts()
で変換します.
intext <- data.frame(age = c("0歳魚", "1歳魚+"),
text = mixfonts(c("(1) 0歳魚", "(2) 1歳以上"),
asciifont = "Arial Rounded MT Bold",
mbytefont = "HGSSoeiKakugothicUB"))
prich <-
pbase +
facet_wrap(~ age, labeller = labeller(age = label_mixfonts())) +
theme(strip.text = element_markdown(size = 15)) +
ggtext::geom_richtext(data = intext, aes(x = 1990, y = 400, label = text),
hjust = 0, label.size = 0, label.color = NA, fill = NA) +
labs(title = "facetタイトル + パネル内")
prich
# 豆腐化した文字をfallback (最後の拠り所) で補完する
fallback_text <- "This is English, この文は日本語です 🚀"
ggplot() + theme(aspect.ratio = 1/2) +
geom_text(aes(x = 0, y = 1, label = fallback_text, family = "Arial"),
size = 3.5)