Skip to content

Instantly share code, notes, and snippets.

@myuhe
Created February 14, 2012 11:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save myuhe/1825991 to your computer and use it in GitHub Desktop.
Save myuhe/1825991 to your computer and use it in GitHub Desktop.

RでSVG素敵生活はじめませんか

昨日に続けて、Rの話題。

今回は、RからSVGで画像を出力してみませんか、というお話です。

Rのグラフィックス

日頃Rを使われている方で、Rから画像を出力したことがないという方はほとんどいないんではないでしょうか。

Rの大きな魅力の一つは、間違いなくこの柔軟かつ豊富なグラフィックス機能です。それは今や個人のみでなく企業でも認知されつつあります。

例えば、MozillaはTest Pilotというアドオンでユーザからのフィードバックデータを視覚化するにためにRのグラフィックスを用いています。

Winners of Mozilla Open Data Competition announced | (R news & tutorials)

Test PilotをFirefoxにインストールすることでFirefoxの利用状況をRのグラフィックスで視覚的に認識することができます。興味のある方はインストールしてみると良いでしょう。

Test Pilot :: Add-ons for Firefox

何を出力していますか?

Rのグラフィックス機能はとても柔軟なのですが、あまりにも選択肢が多すぎてユーザを惑わせます。

その端的なものとして画像の形式があります。

Rから出力できる画像の形式はjpg、pngなどのラスタからsvg、epsなどのベクタまで実に様々なものがあります。この中からユーザは出力する形式を自由に選択することができるのですが、OSやその画像を利用するソフトウェアなどにより強く制約を受けるため、実際には汎用的に扱えるpngやjpgなどのラスタデータに落ち着きがちです。

しかし、標準の関数であるpng()やjpeg()では、出力される画像にアンチエイリアスがかからず、とても残念な画像しか得られません。Cairoパッケージを用いればこの問題は解消しますが、日本語を用いる場合はフォント明示的に指定しないといけないなど、なかなかスマートにいかないのが現状です。また、ラスタデータ自体の問題として拡大すると画像が荒くなるという問題を残しています。

そこで、今回はRからの画像出力の選択肢としてSVGを検討してみました。SVGはxmlフォーマットのファイルであり、テキストデータが持つメリットをそのまま享受できます。

以前は対応するソフトウェアが少ないということで日の目を見なかった可哀想なやつでしたが、近頃はIE9でもサポートされるようになりましたし、WindowsでもInkscapeを使ってemfなどに変換できるため、OSの差異により不自由することはかなり少なくなりました。今後さらに普及が見込めるフォーマットではないかと思います。

実はSVGで出力するのにもいくつか選択肢があります。以降ではその一つ一つについて詳しく見ていきます。

Cairoパッケージ

CRAN - Package Cairo
RでアンチエイリアスしたグラフがプロットできるCairoパッケージ - もうカツ丼でいいよな

Cairoを使って美麗なグラフィックを出力するためのパッケージです。svgだけでなく、pngやjpgについても美しい画像を出力することができます。

ただ、このパッケージについては日本語を使うと文字化けが発生することがあります。フォントを指定することで回避することもできるようですが、svgを出力する関数についてはフォント指定の引数が存在しませんでした。

解決策としてはSVGファイルそのものを編集するという方法もあります。SVGには文字を埋めこむためのtext属性があるため、その要素を修正できれば問題は解決できそうです。しかし残念なことにCairoのsvg関数が出力するSVGは文字をtext属性でなく、ベクタとして出力していました。そのためこの方法も使えないということになります。

svg()関数

R 2.14からはWindowsバイナリにCairoが標準で組み込みとなり、svg()関数にフォントの指定ができるようになっています。というのを@phosphor_mさんから教えてもらいました。いつもありがとうございます!!

R 2.14.0 is released

.bbpBox{background:url(<a href="http://a1.twimg.com/images/themes/theme4/bg.gif">http://a1.twimg.com/images/themes/theme4/bg.gif</a>) #0099B9;padding:20px;}

@dichika @myuhe svg(family=”MS Gothic”);plot(1:10, main=”日本語”);dev.off() ということではないですか??Thu Feb 02 04:26:38 via HootSuite林真広/HAYASHI Masahiro
phosphor_m

これだと標準で使えますし、フォントを指定できるため日本語の文字化けも回避できます。ただ、こちらもCairoパッケージの場合と同様に文字がベクタとして出力されており、SVGを直接編集するということはできません。

RSvgDeviceパッケージ

CRAN - Package RSvgDevice

RSvgDeviceはSVGを出力することに特化したパッケージです。このパッケージの優れている点としては、SVGの可読性が高いという点です。埋めこまれる文字はtext属性の要素となっているため、text属性の要素を変更すれば、埋めこまれる文字を修正することができます。

残念なことに現在は全くメンテがされていないようで、WindowsVistaやWindows7ではplotした瞬間にRごと落ちるという致命的な問題が発生するようです。また、Winでは日本語を使うと文字コードが原因でうまく表示されない場合があるようです。

RSVGTipsDeviceパッケージ

RSVGTipsDeviceは、RSvgDeviceをベースとして多くの改良が施されたパッケージで現在も精力的に開発が進められているようです。

CRAN - Package RSVGTipsDevice

RSvgDeviceを使う時にWindowsVistaやWindows7で発生するような問題も解決している模様。また、面白い機能として出力するSVGにJavascriptが記述されており、ブラウザなどで表示すると任意の場所をマウスオーバーすることでツールチップを表示させることができます。

どれを使うべきか

以上4つの方法ですと、svg()関数かRSVGTipsDeviceパッケージのいずれかを使うのがよろしそうです。

特にsvg()はいろいろとオプションもあり、かなりの優等生です。画像出力の調整をRだけで完結させたい場合はsvg()を用いると良さそうです。

ではRSVGTipsDeviceパッケージの必要性はないのかというと全くそんなことはなく、私自身はむしろ好んでこちらを使うようになりました。

そのメリットはエディタとの親和性の高さです。

Rのグラフィックス機能が確かに豊富で柔軟なのですが、あまりにも豊富すぎて目的とするグラフィックスの変更方法を発見するのに手間どることもしばしばです。また、非常に細かな修正についてはRでカバーしにくいところもあります。

その点、SVGを直接編集すればかなり細かな点まで修正が可能です。

特にEmacs上でのSVG編集は快適そのものです。Emacsの画像表示用メジャーモードであるimage-modeはC-c C-cにテキストデータと画像データをトグルするimage-toggle-displayがバインドされており、画像とXMLを見比べながら画像を編集することができますし、 EmacsにはXML編集のためのメジャーモードもあるので、XML自体の編集も快適です。

また、gnuopack版NTEmacsにはSVGを表示するためにパッチがとりこまれており、問題なくSVGを表示することができます。

emacs for gnupack 24.0.92のビルド(SVGとGnuTLS対応版) - gnupackの開発メモ

HTML5とSVG

HTML5では、SVGの扱いが強化され、HTMLの中にsvgを直接記述できるようになっています。

スタートアップ SVG:第1回 SVGの基礎知識|gihyo.jp … 技術評論社
ASCII.jp:HTML5で注目!インラインSVGの使い方|古籏一浩のJavaScriptラボ

例えば、この日記のようにブラウザ上でグラフを描画したいのであれば、インラインSVGはただhtml中にsvgタグを貼りつけるだけで画像の挿入がすんでしまうので非常にお手軽です。

というわけで早速試してみましょう。まずはシンプルにこんなコード

plot(density(rnorm(100)))

RSVGTipsDeviceパッケージが出力したコードを貼りつけるとこんな感じになります。

R SVG Plot R SVG Plot with tooltips! (mode=1) -3 -2 -1 0 1 2 3 0.0 0.1 0.2 0.3 0.4 density.default(x = rnorm(100)) N = 100   Bandwidth = 0.3363 Density

当然ですが日本語も問題なく使えます。ggplot2使うとこんな感じ。

R SVG Plot R SVG Plot with tooltips! (mode=1) year 増加数 0 500 1000 1500 2000 2002 2004 2006 2008 2010 ほげ ふが ぴよ

Emacsユーザでしたら、Org-babel、R、SVGの組み合わせが最強すぎます。コメントや文章を書きこみながら、org-bebelでRの実行結果を見つつ、作図結果をsvgタグで貼りつけといったことが一つのOrgファイルで完結してしまいます。

Org-babelについては以前にもこの日記で紹介させてもらいました。少し古くなっていますが、少しは参考になるかもしれません。

Emacs上のマルチな実行環境、Org-babel

ちなみにこの日記もOrg-modeで書いています。生のOrgファイルをgistに置いておきますので、実際にOrg-modeでどのように書かれているか見てみてください。

SVGを使った動的グラフィックス

RSVGTipsDeviceパッケージでも用いられているように、JavascriptとSVGを合わせて使うことで動的なグラフィックスを作ることができます。すでにそれを目的としたパッケージも存在します。

例えば、ggplot2やlatticeのような作図システムの基盤となっているgridパッケージを開発したPaul MurrelはgridSVGを開発しています。

gridSVG | Simon Potter

こちらでは作図例を見ることができます。

また、類似のパッケージとしてSVGAnnotationというものもあります。

SVGAnnotation

ブラウザ上でのプレゼンやWebサービスにおけるRの利用はこれからさらに進みそうですので、新たな表現方法としてSVGを使うというのも良さそうです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment