LoginSignup
1
7

More than 3 years have passed since last update.

【R】 ggplot2の美しさを保つ

Last updated at Posted at 2020-02-21

1. 概要

君は美しさを保つため バラのトゲを指に刺した
- 木村カエラ 『鏡よ鏡』

データ視覚化の大定番の{ggplot2}は美しい図表が描ける素晴らしいパッケージですが折角作っても画質が悪かったりカクカクしていたら勿体ないですよね。

ということで今回は、{ggplot2}で作成した図表を美しい状態でエクスポートして優勝していくことにするわ。(一般男性超絶図表描写)1

library(ggplot2)

2. その前に

前提として、こちらの記事を読んでおいてもらえると助かります。
【R】 滑らかなcurveを描こう - Qiita

めんどくせーぞ!

という声も聞こえたので、要点だけざっくりまとめると

  • 曲線はノード(点)同士を結ぶ直線の塊として描写される。
  • ノードを増やせば曲線に近づく
  • より高画質で出力するには一旦SVG等のベクター画像にしてから各種形式に変換する
  • ベクター画像からPNG等に変換時は一回り大きい寸法で出力する

ということです。

3. ggplot2で画質向上を目指す

【曲線に対してノード数を増やす】【ベクター画像で出力する】という基本原理は上記と全く一緒です。
重要なのは、どこにノード数を指定する引数を書くかです。

以下、サンプルコードをこちらから拝借させていただきます。
ggplot2を初歩から要点押さえて使いこなすチュートリアルとコード集

ノード数を設定できないものたち

この章で紹介するものはノード数を増やせないものの、【ベクター画像で出力する】ことによって画質向上が可能です。
各プロットにつき、ベクター画像をInkscapeでPNG変換したものを載せておきます。

散布図

ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) +
    geom_point()

散布図の場合、曲線がないのでノードを増やす必要がありません。
なので、単純にベクター画像として出力すれば万事解決。簡単ですね。

Rplot02.png

折れ線グラフ

サンプルデータセット
library(tidyverse)
df_line <- data.frame(Temperature = rgamma(365, 1, 1)) %>% 
    dplyr::mutate(Lower = Temperature - 3,
                  Upper = Temperature + 3,
                  Date = as.POSIXct(seq(as.Date("2016-01-01"), as.Date("2016-12-30"), by = "days")))
ggplot(df_line, aes(x = Date, y = Temperature)) +
    geom_line() +
    geom_ribbon(aes(ymin = Lower, ymax = Upper), alpha = 0.2)

折れ線グラフはその名の通り直線なので、ベクター化のみで十分です。
塗りつぶした場合も同様です。

Rplot03.png

バイオリンプロット

ggplot(iris, aes(x = Species,y = Petal.Width)) +
    geom_violin()

バイオリンプロットは曲線なのですが残念ながらノード数は設定できないと思われます。
自分の試した範囲では引数を設定しても反映されませんでした。
なのでベクター化による画質向上のみが可能です。
それでも十分滑らかになったと思います。

Rplot04.png

ノード数を設定できるものたち

この章で紹介するものは、
 ① ノード数の増加
 ② ベクター画像としての出力

の2ステップによってかなりの画質向上が期待できます。


こちらは比較用として、各プロットにつき

  • RStudioの標準機能で出力したノード設定前のbefore
  • ノード設定後に出力したSVGをPNGに変換したafter

の2つを掲載しておきます。

密度関数

before
ggplot(iris, aes(x = Petal.Length,y = ..density.., fill = Species)) +
    geom_density(alpha = 0.5)

Rplot07.png

標準の出力ですと画像のようにカクカクしていて、なんかとても惜しいですね。
そこで、密度関数が曲線となっている場合、ノード数を増やすことで滑らかにできます。

afer
ggplot(iris,aes(x=Petal.Length,y=..density..,fill=Species))+
    geom_density(alpha=0.5 , n = 50000) # ココに引数nを追加

もちろん、ベクター画像で出力することを忘れずに。

Rplot06.png

回帰線

before
ggplot(data = iris, aes(x = Sepal.Length,y = Sepal.Width)) +
    geom_point() +
    geom_smooth() + # 回帰線
    theme_bw()

Rplot08.png

こちらも標準だとカクカクでお世辞にも美しいとは言えません。

モデルによりますが、曲線の回帰線であればノード数を増やすことで滑らかにできます。
なお直線の場合でもノード数自体は増やせるようですが、直線は2点を真っ直ぐつないだものなので恩恵がないです。

after
ggplot(data = iris, aes(x = Sepal.Length,y = Sepal.Width)) +
    geom_point() +
    geom_smooth(n = 50000) + # ココに引数nを設定
    theme_bw()

Rplot09.png

4. おわりに

カクカクに悩まされたら、とりあえずベクター画像に保存するだけでもだいぶ改善されます。
プラスで、引数nが設定できそうであれば、ダメ元で打ってみるとよいでしょう。引数nに関するエラーが出なければ、ノード数が反映されていることが多いです。
RStudioのビューアーは解像度がよろしくないので、RStudio上でnが反映されているかどうかを確認するには、あえて低いノード数を設定するほうがわかりやすいです。

ちなみに、n = 11にしたときの密度関数のプロットなこんな感じになります。ぜひ比較してみてください。

Rplot.png

キレイにエクスポートできれば、気合を入れて作った図表が映えますね。
さぁ皆さんも、レッツggplot!!!!

Enjoy!

おしまい。

1
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
7