読者です 読者をやめる 読者になる 読者になる

ggplot2 日本語用テーマ

ggplot2-0.8.7 で、テーマ theme_gray() を日本語向けに直してみよう。


数ヶ月前に ggplot2 でフォントファミリー・サイズを変更できるようなテーマを作りました。
ggplot2 は当然英字出力で調整しているはずなので、日本語を含む場合はファミリーやサイズによっては変な出力になります。
例えば、軸ラベルに漢字を含む場合はこんな状態に・・・


axis.title.x の位置が高すぎるので、

axis.title.x = theme_text(family = family, size = base_size, vjust = 0.5)
↓
axis.title.x = theme_text(family = family, size = base_size, vjust = -0.5)

また、plot.margin が少なすぎて、軸ラベルがめり込んでしまうようなので、

plot.margin = unit(c(1, 1, 0.5, 0.5), "lines")), class = "options")
↓
plot.margin = unit(c(1, 1, 1, 0.5), "lines")), class = "options")

これで、かなり改善できるようです。
ただし、unit(c(1, 1, 1, 0.5), "lines")) の設定順序は ↑→↓← らしい。

少し薄い印象もあるけど、メイリオでも充分きれいに見えるなぁ。


あとは、グラフ描画領域をぴったり 0 から始まるように (描画領域–軸ラベル値間のマージンを 0 に) したかったのですが、自動でマージンが入ってしまうのでどうしたらいいのか分からず。暇なときにまた調べてみようかなぁ・・・い場合は、scale_x_continuous(expand = c(0, 0))、または scale_x_discrete(expand = c(0, 0)) などを使用すればよいでしょう。

require(ggplot2)
require(grid)
if (is.na(commandArgs()[6])) {
  path <- "C:/";
} else {
  path <- commandArgs()[6];
}

d <- data.frame(
sc=c(
"竹-1","竹-3","竹-3","松-2","松-2","梅-2","梅-2","竹-1","竹-1","松-2","竹-2","松-2",
"梅-2","梅-2","竹-2","松-3","竹-3","竹-1","竹-1","竹-1","竹-1","梅-2","竹-1","竹-1",
"竹-1","竹-1","竹-1","竹-1","竹-1","竹-1","梅-1","梅-2","梅-2","竹-1","竹-1","竹-1",
"竹-1","竹-1","梅-1","竹-1","梅-2","梅-1","梅-1","梅-2","梅-2","梅-2","梅-2","梅-2",
"竹-3","竹-3","竹-3","竹-3","梅-2","竹-3","梅-2","梅-2","梅-2","梅-2","竹-1","竹-1",
"竹-3","梅-2","梅-2","梅-2","竹-1","竹-1","梅-2","竹-1","竹-1","竹-1","竹-1","梅-1",
"梅-1","梅-1","竹-1","竹-1","竹-1","竹-1","竹-1","竹-1","竹-1","梅-1","梅-1","竹-3",
"竹-3","梅-2","梅-1","梅-1","竹-1","梅-1","梅-1","梅-1","梅-1","竹-1","梅-3","梅-3",
"竹-1","梅-3","竹-1","梅-3","梅-1","梅-1","竹-1","竹-1","竹-1","梅-1","梅-1","梅-1",
"梅-1","梅-1","梅-1","梅-1","松-1","梅-1","竹-1","竹-1","梅-1","竹-1","竹-1","竹-1",
"竹-1","竹-1","竹-1","松-2","竹-1","梅-1","梅-1","梅-1","梅-1"))

#######################################################################
mytheme_gray <- function (base_size = 12, family = "") {
  structure(list(
    axis.line = theme_blank(),
    axis.text.x = theme_text(family = family, size = base_size * 0.8,
      lineheight = 0.9, colour = "grey50", vjust = 1), 
    axis.text.y = theme_text(family = family, size = base_size * 0.8,
      lineheight = 0.9, colour = "grey50", hjust = 1),
    axis.ticks = theme_segment(colour = "grey50"), 
    axis.title.x = theme_text(family = family, size = base_size, vjust = -0.5), 
    axis.title.y = theme_text(family = family, size = base_size, angle = 90, 
      vjust = 0.5),
    axis.ticks.length = unit(0.15, "cm"), 
    axis.ticks.margin = unit(0.2, "cm"),
    legend.background = theme_rect(colour = "white"), 
    legend.key = theme_rect(fill = "grey95", colour = "white"), 
    legend.key.size = unit(1.2, "lines"),
    legend.text = theme_text(family = family, size = base_size * 0.8),
    legend.title = theme_text(family = family, size = base_size * 0.8,
      face = "bold", hjust = 0),
    legend.position = "right",
    panel.background = theme_rect(fill = "grey90", colour = NA), 
    panel.border = theme_blank(),
    panel.grid.major = theme_line(colour = "white"), 
    panel.grid.minor = theme_line(colour = "grey95", size = 0.25), 
    panel.margin = unit(0.25, "lines"),
    strip.background = theme_rect(fill = "grey80", colour = NA),
    strip.text.x = theme_text(family = family, size = base_size * 0.8),
    strip.text.y = theme_text(family = family, size = base_size * 0.8,
      angle = -90),
    plot.background = theme_rect(colour = NA, fill = "white"),
    plot.title = theme_text(family = family, size = base_size * 1.2),
    plot.margin = unit(c(1, 1, 1, 0.5), "lines")), class = "options")
}
#######################################################################

windowsFonts(Meiryo="メイリオ")
p <- ggplot(d, aes(x=sc)) + geom_bar(aes(fill=..count..)) +
     mytheme_gray(base_size=26, family="Meiryo") + xlab("なんとか群スコア") +
     ylab("人数") + scale_fill_gradient("人数")

ggsave(paste(path, "ggplot2x.png", sep=""), p, width=10, height=10)

追記 (2012/09/05)

この記事は ggplot2-0.8.7 の時に書かれたものです。
仕様変更のため、最新のバージョンでは動かない場合があります。
ggplot2-0.9.0 以降では、この記事のような形で unit 関数を利用する場合には、grid package のロードが必要となります。

ggplot2-0.9.2 では以下の様に書くことができますし、マージン等もデフォルトで微調整されています。

mytheme_bw <- function(base_size = 12, base_family = "") {
  
  theme_bw(base_size = base_size, base_family = base_family) %+replace%
  theme(
    axis.text.x = element_text(vjust = 1),
    plot.margin = grid::unit(c(1, 1, 0.5, 0.5), "lines")
  )

}

追記 (2012/05/25)

この記事を書いた当時はなかったのですが、ggplot2-0.8.9 以降では theme 系関数の引数に base_family が追加されています。
また、theme のマージンなども若干変更されていたりしますので、最新版に合わせて適宜パラメータを調整すると良いかもしれません。