<< (newer post) (older post) >>     

他のアプリを操作する

Julia から OS にコマンドを投げて他のアプリケーションを起動することができる. 起動だけなら

run(`コマンド`)

とすれば良い(Julia では,外部へ渡すコマンドはバッククォーテーション ` で囲む). ただし run 命令はそのコマンドを投げっぱなしで出力結果などはもらえないので,出力が欲しい場合は

readall(`ls`)

などとすればそのコマンドの標準出力結果をもらうこともできる.

さらに,動作中のそのアプリケーションと,標準入出力を用いてデータをやり取りもできる. それには readandwrite 命令を使って外部アプリを起動すれば良い(引数の与え方は runreadall と同様). そして,返り値として標準出力、標準入力、プロセスオブジェクトをもらえる. 例えば gnuplot を操作したければ次のような感じで gnuplot を起動する.

(so,si,pr) = readandwrite(`gnuplot.exe`)

そしてこの標準入力 si にデータを流し込むとそれが gnuplot へのキーボード入力と同等に扱われるというわけだ. ちなみに

close(pr)

とすればこのアプリケーションを閉じることができる(タスクマネージャーなどで見てると確認できるぞ).

だから,gnuplot を使って単純なグラフを描かせるだけなら,次のようにすればいい.

(so,si,pr) = readandwrite(`gnuplot.exe`)
println(si, "plot sin(x)")

ちなみに,これを実行すると背後にいきなり別画面で gnuplot のグラフが現れてびっくりする…

さらにちょっと応用編として,上のように関数ではなくてデータを gnuplot に渡してグラフを描かせて,それを Jupyter の画面に表示するなんてのは, gnuplot のヒアドキュメント機能と,Julia の Images パッケージを使って次のようにすれば良い.

# readandwrite コマンドで、他のアプリを起動できる.結果として、標準出力、標準入力、プロセスオブジェクトを貰える.
(so,si,pr) = readandwrite(`gnuplot.exe`)

# gnuplot に、出力前の準備コマンドを渡す.標準入力に書き込むだけで、内容はごく普通.
fn = "dummy-g.png"
println(si, "set output \"$fn\"")
println(si, "set terminal png")
println(si, "unset key")

# 出力するデータ.
N = 300
y = randn(N)

# ある程度新しい gnuplot は、ヒアドキュメント機能を持っている.
# 要するに、「次の行から、行頭がhogehoge という行までの入力」を << の左にある変数(= データブロック)に設定できる.
# ちなみに,gnuplot には「データブロックはその名前の最初の文字を $ にする」というルールがあるので注意.
# まあともかく,この機能を使えば、ダミーのファイルに書き込んだりしなくても、標準入力で gnuplot にデータを直接渡せる.
println(si, "\$data << EOD")
for i in 1:N
  println(si, "$(y[i])")
end
println(si, "EOD")

# あとは gnuplot にプロットさせるだけ.
println(si, "plot \$data w lp")
println(si, "set output")
println(si, "exit")

# 上の "exit\n" で gnuplot 自身が停止したはずだが,
# 起動したプログラムを close で閉じることができるので念のため.
close(pr)

# gnuplot が画像ファイルを生成するよりも julia が次のコマンドを実行するほうが早いw.
# そのため、待ってあげないと(ほんの少しでよい)、画像ファイル読み込みに失敗する.
sleep(0.2)

# 試しに、作ったプロット画像を Jupyter へ読み込んでみる.
using Images
load("dummy-g.png")

すると aa といった感じのグラフが瞬時に web (Jupyter)上に現れる.

「PyPlot はよくわからんが gnuplot なら慣れてるぜ!」という人はこうしてグラフを描かせるようにするといいかもしれない(適当にパッケージングしておくといいかもね).

さらなる応用として,グラフをたくさん描かせて ffmpeg あたりで動画に変換するというのもやっておくと良さそうだ.

そうなると,Julia でデータを計算して,(見かけ上) Julia でそのグラフを描いて,(見かけ上) Julia でその動画も作って,とできるので,いろいろと操作が閉じて一貫性があって良いかなと思う.

     << (newer post) (older post) >>