Jupyter R kernel で ggplotグラフに日本語が表示されない問題に対処


Ubuntuの場合

Jupyter notebook 上で下記のRコードを実行すると、

library(ggplot2)

d <- data.frame(x=c("ABC", "DEF", "GHI"), y=c(1, 2, 3))
ggplot(d, aes(x, weight=y)) +
  geom_bar(fill="gray50", color="gray10") + geom_text(aes(y=y, label=x)) +
  xlab("horizontal label") + ylab("vertical label") + ggtitle("Title")

d <- data.frame(x=c("あいうえお", "かきくけこ", "さしすせそ"), y=c(1, 2, 3)) 
ggplot(d, aes(x, weight=y)) +
  geom_bar(fill="gray50", color="gray10") + geom_text(aes(y=y, label=x)) +
  xlab("横軸") + ylab("縦軸") + ggtitle("タイトル")

自分のUbuntu 18.04環境では以下の出力になった。日本語がすべて空白になっている。




いろいろな情報を見た。以下のいずれもうまくいかなかった。

  • theme(text=element_text(family="font-name")) でフォントを指定
  • extrafonts でフォントをロード
  • quartzFonts()でフォント名を登録

エラーも警告もなく、ただ表示されない状態だった。
ところが、ggsave を使ってファイルに書き出すときちんと出力されているようだった。そこで、根本的な対処は分からなかったが、グラフを一時ファイルに書き出してそれを表示させる方式をとった。

ggshow <- function(g=last_plot(), dispwidth=600, dispheight=NULL, tmpdir="ggtmp", ...) {
  # show ggplot graph
  # a quick workaround to the issue where
  # Japanese texts are not displayed on the notebook
  if (!dir.exists(tmpdir)) {
    if (file.exists(tmpdir)) {
      stop(sprintf("'%s' already exists as a file.", tmpdir))
    }
    dir.create(tmpdir, recursive=TRUE)
  }

  tmpfile <- file.path(tmpdir, "tmp.jpg")
  ggplot2::ggsave(tmpfile, g, ...)
  IRdisplay::display_jpeg(file=tmpfile, width=dispwidth, height=dispheight)
}

ggshow()

ggshow 関数について

  • g に表示したいggplotオブジェクトを指定。
  • dispwidth, dispheightで表示サイズを指定。片方だけ指定すると縦横比固定で調整される。
  • ...ggsaveへ渡されるので、width, height などを指定してサイズ変更ができる。

一応目的は達成できるものの、根本的に解決する方法があるならぜひ教えてほしい・・・。

MacBookの場合

MacBookで同じコードを実行すると、大量の警告が出ていわゆる「豆腐」が表示された。フォントが対応していないのが原因のようだ。
対処法としては、この記事を参考に、以下のステップを取った。

  1. 自分の持っているフォントを確認
  2. 好きな日本語フォントをに登録
  3. グラフ作成時にフォントを指定

自分の持っているフォントを確認

systemfonts::system_fonts() を使うと便利。しかし出力量が多いので、例えば次のようなコードでフォント名に当たりを付けて検索する。

library(dplyr)
systemfonts::system_fonts() %>% filter(grepl("Hira", family)) %>% select(name, path)

HiraginoSans-W8     /System/Library/Fonts/ヒラキノ角コシック W8.ttc
HiraginoSansGB-W6   /System/Library/Fonts/Hiragino Sans GB.ttc
HiraginoSans-W6     /System/Library/Fonts/ヒラキノ角コシック W6.ttc
HiraMaruProN-W4     /System/Library/Fonts/ヒラキノ丸コ ProN W4.ttc
...

好きな日本語フォントを登録

描画には quartzFonts というのが使われるらしいので、上で見つけたフォントを登録する。
4つ繰り返しているのは「標準」「太字」「イタリック」「太字・イタリック」の4種類登録する仕様に対応するため。
同じフォントでもグラフ描画ではあまり困らないので区別していない。

quartzFonts(hiragino=rep("HiraMaruProN-W4", 4))  # 登録
quartzFonts()  # 結果を確認

$serif
'Times-Roman''Times-Bold''Times-Italic''Times-BoldItalic'
$sans
'Helvetica''Helvetica-Bold''Helvetica-Oblique''Helvetica-BoldOblique'
$mono
'Courier''Courier-Bold''Courier-Oblique''Courier-BoldOblique'
$hiragino
'HiraMaruProN-W4''HiraMaruProN-W4''HiraMaruProN-W4''HiraMaruProN-W4'

グラフ作成時にフォントを指定

  • グラフの軸やタイトルのフォントは theme(text=element_text(family="font-name")) で指定できる。
  • 文字列をプロットする場合、geom_textfamilyオプションでフォントをを指定できる。
jofont <- "hiragino"
d <- data.frame(x=c("あいうえお", "かきくけこ", "さしすせそ"), y=c(1, 2, 3)) 
# gets warnings, but works
ggplot(d, aes(x, weight=y)) +
  geom_bar(fill="gray50", color="gray10") + 
  geom_text(aes(y=y, label=x), family=jpfont) +
  xlab("横軸") + ylab("縦軸") + ggtitle("タイトル") +
  theme(text=element_text(family=jpfont))

ノートブックで実行したところ、大量の警告 “ ポストスクリプトフォントのデータベースにフォントファミリ 'hiragino' が見付かりません ” を出しながらもグラフがちゃんと出力された。

警告が嫌な場合、suppressWarnings を使って出力を避けることができる。
または、上で定義した ggshow 関数はMacBookでも機能する。

実行例

本記事の実行例(Gist)