Rのポストスクリプト画像(eps・psファイル)出力
とりあえずは自分用のメモのレベルです。
万一参考になればということで公開していますが。
期待せずご覧ください。
忙しい人のためのまとめ
postscript
で開きます。file
引数はファイル名(epsまたはps)。width
とheight
はインチ単位のカンバスサイズです。
paper
は用紙サイズで"special"
固定。horizontal
はFALSE
固定で運用します。でないと、文書ファイルに貼るときに図が回転しちゃったり。
描画範囲の設定がおかしくなったりするかもしれません。
(ケースバイケースなので、問題ないこともあります。)
フォントの埋め込みには
embedFonts
関数を使用します。ただしGhostscriptのインストールと環境変数設定が必要です。
eps画像の基本
まずはそもそもepsってなんぞな、というトコロを簡単に。
ご存知のかたは読み飛ばしてください。
epsとベクタ画像
もともとpostscript(ps)という形式の画像形式があり。
それをちょっと拡張したのがeps形式です。
Rの
postscript
関数はどちらも保存できるので。自分の用途において使いやすいほうを選べばOKです。
それはベクタ形式(ベクトル形式)であること。
ベクタ画像は、図を構成するオブジェクト情報のあつまりなので。
拡大・縮小しても画質が劣化しません。
ラスタ形式において、画像は色点の集合として描画されているため。
縮小してるうちに1ピクセル未満になった点や線が消えたり。
拡大したら境界線がぼやけたり。
学術データのグラフには致命的な現象が起こります。
基本的にデータサイズを抑えるための圧縮がかかるし。
その結果として、近傍領域がティザ状ににじむ傾向がある。
そんな形式でグラフを保存するとか、ありえません。
散布図の点がにじんでさらに散布してたら、笑うでしょ?
グラフデータの保存にはベクタ画像が向いていて。
そのなかでは身近な形式がポストスクリプトなのです。
ベクタ形式の画像ファイル
ざっと思いつくところでは、
- eps (Encapsulated PostScript)
- ps (PostScript)
- svg (Scalar Vector Graphics)
- wmf (Windows Metafile)
- pdf (Portable Document Format)
- ai (Adobe Illustrator)
現にあたしも、初期にはpdfでグラフを出力していました。
ただ、pdfは「完成したひとつづりの文書」を単位とする設計なので。
「パーツとしての個別の図」の保存には、細かいトコで不便です。
(具体的には用紙や描画領域の扱いなど。)
これはAdobeがIllustrator用に策定した独自の形式。
あくまで「イラレのセーブデータ」です。
仕様も非公開なうえ、頻繁に改定されるので。
今回の用途には向いていません。
他のドロー系ソフト(inkscapeなど)用の形式も同様です。
svgやwmfなどは、Rから直で出力できるので。
epsよりもそちらがよければ、ヘルプを参照してください。
(wmfはWindows版のみ。)
使い方は本稿で説明するepsとほぼ変わりません。
標準LaTeXで親和性の高いepsを愛用。
ちなみにポストスクリプト形式は、印刷業では業界標準。
Windows環境では、対応ソフトが少なくて不便かもしれませんが。
LinuxやMacではデフォルトの画像閲覧ソフトで開けるし。
昔よりも身近な存在になってきてる気がします。
Rとeps画像
postscript関数
- デバイスを開く
- 描画処理を行なう
- デバイスを閉じる
その後「閉じる」までの描画がカンバス上になされます。
カンバスとしてpngデバイスを開けばpng画像が。
psデバイスを開けばポストスクリプト画像が保存される、と。
postscript
関数。これを使って、ファイル名を
.eps
ないし.ps
の拡張子にし。あとはフツーに描画処理をすればOKです。
dev.off
で閉じるまではコネクションが開きっぱなしなので。描画が終わったらとっととデバイスを閉じる。
これも他の形式での画像出力と変わりませんね。
file引数
file
引数は出力する画像のファイル名です。他の画像形式と同様、連番ファイル名なども使えます。
width・height引数
width
とheight
。これらは正確には「描画領域のサイズ」を決めています。
また
postscript
は、サイズをインチで指定します。ピクセル単位だと勘違いして640×480などとすると、
Rのデフォルトの描画ウィンドウ(※)が7インチ四方なので。
(※ 外部デバイスを開かずに
plot
すると出るウィンドウ)まずはそのぐらいのサイズで様子をみるといいでしょう。
ちなみに1インチは25.4ミリです。
出力したepsファイルは、他の原稿に貼り込んだりして使うわけで。
その際、原稿の幅にあわせて拡大・縮小するはずです。
よって、元の画像が単体で何インチ四方かは関係ないですし。
ベクタ画像なので、引き伸ばしても画質の劣化はありません。
描画領域を変えても、このサイズは連動しません。
たとえば
width
・height
を増すと、描画領域だけが大きくなり。画像全体に対して、文字や線は相対的に小さく・細くなります。
width
とheight
の指定は、
相対的な文字や線のあんばいをみて調整しつつ。
ほどほどのサイズにしておきましょう。
(わたしの場合、一枚モノの図ではたいがい10以下です。)
paper引数
width
とheight
で「描画領域」のサイズを決めましたが。epsには、それとは別に「用紙」のサイズというものがあります。
これを指定するのが
paper
引数です。
paper
のサイズは、実際の印刷時の用紙とは無関係ですし。描画内容は描画領域という「小箱」のなかに描かれるので。
描画領域部分だけを切り取ってみれば、中身は変わらないからです。
10センチ四方の枠を引いて、そのなかに絵を描くことにします。
この枠が描画領域にあたります。
この枠を基準に描けば、用紙全体の大きさは関係ないですよね?
用紙がA4でもB5でも、そのなかの10センチ四方の部分が内容であって。
余白になる領域の多さが変わるだけです。
枠の外を切り取ってしまえば、できあがるものは変わりません。
paper
には"a4"
とか"letter"
とか選べますが。サイズの観点からは、どれを選ぶべきということはありません。
…が、ここでちょっと別の問題がありまして。
paper
は"special"
を指定するようにしてください。
"special"
というのは
たとえば
width = 6, height = 4
なら、用紙も6×4インチになります。「その描画内容に特注サイズの用紙」という意味での
"special"
ですね。
"special"
以外だと、できたeps画像の座標情報が狂うことがある具体的には、LaTeXに貼ったとき天地が逆転してしまいます。
他のソフトに貼り込む場合にも、問題が生じるかもしれません。
paper = "a4"
paper = "special", width = 210/25.4, height = 297/25.4
(25.4で割るのはミリからインチへの変換。)
しかし内部的には「A4」と「210×297の特注サイズ」は違うものらしく。
前者の場合のみ、
paper
を"special"
以外にしても、問題ないこともあります。また、おそらくこの挙動は仕様というよりバグなので。
今後のRのアップデートで解消されるかもしれません。
用紙サイズはつねに
"special"
で描画領域にフィットさせればOKです。
horizontal引数
horizontal
という引数があります。horizontalは「水平」なので、ちょっとカンのよいひとは、
horizontal
引数は
たとえば6×4のヨコ長グラフを出力したいとします。
その場合、たんに
width
とheight
で
width = 6, height = 4
horizontal
はFALSE
にしておきます。

horizontal = FALSE, width = 6, height = 4
horizontal = TRUE
だろう」
horizontal = TRUE, width = 6, height = 4
horizontal
をTRUE
にすると図が90°回転します。また、加えて
width
とheight
も自動的に逆転されます。結果、できあがる画像のファイルとしての横は4インチ、縦は6インチ。
画像ファイルとしてはタテ長になっています。
描画内容にとっては、タテが幅、ヨコが高さ。
90°首をかしげてみると、ヨコ長の図になっています。
horizontal
引数は、
- 中身を90°回転させて描画する
- その際、もとの指定の
width
とheight
を逆転する - 結果、図の内容的にはもと通りの縦横比が保たれる
ようはあのノリです。
だって、図の回転なんぞ原稿作成時にすればいいわけで。
個々のパーツとしての図の段階で、回転しとく意味はないからです。
1つひとつの図は、全部フツーに正立で準備しておいて。
原稿を書く段階で、ページにおさまらなければ回転すればよい。
なので、
horizontal
はFALSE
固定でよいと思います。
和文フォントの扱い
epsのフォント問題
これにより、拡大・縮小しても文字がつぶれる心配は消えますが。
(単純に小さすぎて読めないというケースはべつとして。)
そのかわり、文字化けなどの新たな問題の可能性が浮上します。
その画像内では、とくに変更しなければそのフォントが使われます。
postscript
関数の場合、フォント設定を担うのはfamily
引数。前節ではこの引数についてはとりあげませんでしたが。
デフォルトで
"Helvetica"
が指定されています。
Helvetica
は和文のフォントを含んでいませんので。軸ラベルや凡例に和文を使いたくても、そのままでは表示できません。
x11(width = 3, height = 3)
par(mar = c(3.5, 3.5, 0.5, 0.5), mgp=c(2.5, 1, 0))
plot(0, 0, xlab = "x軸", ylab = "y軸", type = "n", bty = "l")
text(0, 0, "和文ためし")
などとすると、問題なく日本語が表示できますが。epsデバイスにおなじ描画をすると、ドットに化けてしまいます。

描画ウィンドウでの和文テキスト表示

epsファイルでの和文表示エラー
表示すべき文字が
Helvetica
というフォント内に存在しない
Helvetica
にそんな字ねーぜ」postscript
で使えるフォントは以下のように確認できます。
> names(postscriptFonts())
[1] "serif" "sans" "mono"
[4] "AvantGarde" "Bookman" "Courier"
[7] "Helvetica" "Helvetica-Narrow" "NewCenturySchoolbook"
[10] "Palatino" "Times" "URWGothic"
[13] "URWBookman" "NimbusMon" "NimbusSan"
[16] "URWHelvetica" "NimbusSanCond" "CenturySch"
[19] "URWPalladio" "NimbusRom" "URWTimes"
[22] "ArialMT" "ComputerModern" "ComputerModernItalic"
[25] "Japan1" "Japan1HeiMin" "Japan1GothicBBB"
[28] "Japan1Ryumin" "Korea1" "Korea1deb"
[31] "CNS1" "GB1"
これらがpostscript
のfamily
引数に指定できるフォントの一覧です。
ありがたいことに、最近のRには和文フォントがもとから入っています。
"Japan1"
ではじまるフォントファミリーですね。それぞれの実体は
postscriptFonts
のヘルプにあるとおり、
Japan1
... 平成角ゴシック(HeiseiKakuGo-W5)Japan1HeiMin
... 平成明朝(HeiseiMin-W3)Japan1GothicBBB
... 中ゴシックBBB(GothicBBB-Medium)Japan1Ryumin
... リュウミンライト(Ryumin-Light)

postscript
で使用可能な和文フォントファミリ
なので
"Japan1"
か"Japan1GothicBBB"
が選択肢となります。いずれにしても、選んだフォントを
family
引数に指定してやり。あとは普通にグラフ出力をすればOKです。
postscript("test.eps", paper = "special", horizontal = FALSE,
width = 3, height = 3, family = "Japan1GothicBBB")
par(mar = c(3.5, 3.5, 0.5, 0.5), mgp=c(2.5, 1, 0))
plot(0, 0, xlab = "x軸", ylab = "y軸", type = "n", bty = "l")
text(0, 0, "和文ためし")
dev.off()

family = "Japan1GothicBBB"
を指定したeps画像
軸目盛の数字などもほんの少し丸っこくなっています。
これは半角英数も含めて文字がすべて
Japan1GothicBBB
になっているためです。(全角になっているわけではありません。)
family
引数に指定したフォントは、一括で適用されます。
- 部分によって違うフォントを使う
- 途中で和文フォントを切り替える
いまのところわたしはそういう方法を知りません。
もし知ってるひとがいたら教えてください。
postscriptFonts
のヘルプによると
'In use' means that it has been specified via a 'family' or
'fonts' argument to an invocation of the same graphics device
already in the R session.
フォントの埋め込み
postscript
関数は、フォントを埋め込みません。上記のとおり、
family
の指定でeps画像上に和文を表示できましたが。これはあくまで
Japan1GothicBBB
というフォントを使って表示してくださいな」閲覧環境にそもそもそのフォントがなければ、やはり表示できません。
日本語環境であればまず入っているとは思いますが。
英語版のOSなどを使っていると、未インストールかもしれません。
(そんな環境で使う図には、そもそも和文は使わないでしょうが。)
さっきの例でいえば
Japan1GothicBBB
ってのはコレだからどうぞ使ってよ」embedFonts
関数。フォントの埋め込みをしたいepsファイルを指定してやると。
内部で使われているフォントを画像ファイルに埋め込んでくれます。
embedFonts("test.eps")
デフォルトでは指定した画像ファイルに上書き保存されますが。別のepsファイルとして出力することも可能です。
embedFonts
の利用にはGhostscriptというソフトが必要です。というか、
embedFonts
はGhostscriptを呼び出しているだけにすぎず。実際の埋め込み作業はGhostscriptがやっています。
apt
で。
$ sudo apt-get install ghostscript
$ gs -v
GPL Ghostscript 9.10 (2013-08-30)
Copyright (C) 2013 Artifex Software, Inc. All rights reserved.
Windowsでは東大数理科学研究科 大島研のミラーなどから取得してください。
gs
コマンドがすぐ使えるので。それだけで
embedFonts
も使えるようになります。Windows環境でも、運がよければRがGSを自動でみつけてくれますが。
場合によっては、Ghostscriptの場所を明示的に示す必要があります。
実行形式のGS本体は
C:\gs\gs8.64\bin\gswin32c.exe
といったカンジになります。これをRターミナル内で
Sys.setenv
を用いて
Sys.setenv("R_GSCMD" = "C:\gs\gs8.64\bin\gswin32c.exe")
のようにR_GSCMD
という環境変数にセットしてやるか。あるいはマイコンピュータから同名の環境変数に設定してください。
([システム情報の表示]→[詳細設定]→[環境変数]→[ユーザー環境変数])
先の例の「和文ためし」のepsファイルは、もとは5.1kBでしたが。
embedFonts
のあとでは101.1kBになっていました。
embedFonts
は、option
引数からGSへの制御ができて。"-dSubsetFonts=true"
をつけると、サブセット埋め込み。"-dEmbedAllFonts=true"
だとフルセットの埋め込みになるハズですが。わたしの環境では、どちらも埋め込み後のサイズは変わりませんでした。
"special"
の用紙サイズを許容しないようで。embetFonts
すると、epsのサイズが"a4"
になって余白が生じます。そのため実用的には、ここでも
option
引数を利用して
embedFonts("test.eps",
options="-dDEVICEWIDTHPOINTS=216 -dDEVICEHEIGHTPOINTS=216")
のように、画像サイズをGSに伝えるとよいでしょう。postscript
のデフォルトeps出力は72dpiなので、指定するサイズは
(上記の例では3インチ四方なので216です。)