SVG画像

[2016-01-25] svglite,rsvgを追加しました。

[2016-11-15] svglite 1.2.0についての情報を追加しました。

はじめに

グラフをSVG形式で描くには,ほぼR標準(cairo)の svg() を使うか,RSVGTipsDeviceパッケージの devSVGTips() を使うという選択肢がありました。2015年末にはHadley Wickhamが新しい svglite というパッケージを作りました(アナウンス,GitHubの hadley/svglite)。

cairo版では,文字も図形になり,ビューアに依存しないので安心ですが,日本語を使う場合は下の例のように日本語のフォント名を指定する必要があります。RSVGTipsDevice版では,SVGの <text> を使ってそのままUTF-8の文字列を書き込みますので,表示はビューアに依存しますが,文字列は検索・コピー可能になります。ツールチップ(マウスを乗せると現れる吹き出し)を埋め込むこともできます。svglite版はファイルサイズが他よりずっと小さいSVGを出力します。

Macで普通に画面に描いてスクリーンショットをとります:

quartz(width=7, height=4)
par(mgp=c(2,0.8,0))
curve(dnorm(x), xlim=c(-3,3), main="正規分布")
Quartzグラフィックの例

標準(cairo)の svg() を使います:

svg("dnorm-cairo.svg", family="Japan1GothicBBB", width=7, height=4)
par(mgp=c(2,0.8,0))
curve(dnorm(x), xlim=c(-3,3), main="正規分布")
dev.off()
CairoのSVGの例

RSVGTipsDevice の devSVGTips() を使います:

library(RSVGTipsDevice)
devSVGTips("dnorm-svgtips.svg", width=7, height=4)
par(mgp=c(2,0.8,0))
curve(dnorm(x), xlim=c(-3,3), main="正規分布")
dev.off()
RSVGTipsDeviceのSVGの例

svglite の svglite() を使います:

library(svglite)
svglite("dnorm-svglite.svg", width=7, height=4)
par(mgp=c(2,0.8,0))
curve(dnorm(x), xlim=c(-3,3), main="正規分布")
dev.off()

生成された図は幅情報がなく,画面幅いっぱいに出力されてしまうので,ここでは <img src="..." width="600" alt=""> のように幅を指定しています。

svgliteのSVGの例

日本語の部分だけ位置がおかしくなってしまいました。気になるなら

<text x='266.40' y='34.67' style='font-size: 14.40pt; font-weight: bold;
  font-family: Arial;'>正規分布</text>

<text x='266.40' y='34.67' style='font-size: 14.40pt; font-weight: bold;
  font-family: sans-serif;' text-anchor="middle">正規分布</text>

に直せばよさそうです。ついでですので,Arial になっているところを全部 sans-serif に直し,dnorm(x) と書いてあるところだけ monospace に直してみました(以下参照)。

[2016-11-15追記] svglite 1.2.0 が出ました。CJK supportを謳っているのですが,文字幅の取得にたいへん時間がかかり,しかもあまり美しくありません:

svglite 1.2.0のSVGの例
<text x='245.40' y='34.53' style='font-size: 14.40px; font-weight: bold; font-family: Arial;'
  textLength='42.00px' lengthAdjust='spacingAndGlyphs'>正規分布</text>

単純に中央揃えをサポートしてくれたほうがよかったのに。

rsvgによる変換

librsvgはGNOMEプロジェクトの一環として開発されているSVGライブラリです(当初の開発者はRaph Levien)。これをRから使えるようにしたのが rsvg パッケージです。これを使えばSVG画像をPDFや任意解像度のビットマップ画像に変換できます。

以下では,前節の最後に書いたように修正したsvglite出力を使います。

library(rsvg)
bitmap = rsvg("dnorm-svglite.svg", width=600)
png::writePNG(bitmap, "dnorm-svglite.png")
svgliteのSVGをrsvgでpngにしたもの

PDFに変換するには次のようにします:

rsvg_pdf("dnorm-svglite.svg", "dnorm-svglite.pdf")

変換したPDFはちゃんとフォントが埋め込まれています:

svgliteのSVGをrsvgでPDFにしたもののフォント

sans-serifserif に直したり font-weight: bold; を外したりしてみると,Mac(El Capitan)では欧文にHelveticaやTimes-RomanやCourier,和文にHiraginoSans-W3,HiraginoSans-W6,HiraMinProN-W3,HiraMinProN-W6が使われることがわかりました。

Windowsで同様にやってみると,和文CairoFont-1-1,欧文DejaVuSans,DejaVuSansMonoが埋め込まれるようです。

Linux(CentOS 7)でもやってみました。あらかじめ yum install librsvg2-devel してからrsvgをインストールします。フォントは和文CairoFont-1-1,欧文DejaVuSans,DejaVuSansMono,数字VL-Gothic-Regularが埋め込まれます。VL Gothicの数字は0に斜線が入ります。


Last modified: