数値を得たら、プロットしてみるということはしばしばあります。 pythonだとmatplotlibを使ったりしますが、 gnuplotを呼び出すことができれば、 グラフ描画をgnuplotにまかせることもできそうです。
gnuplotは、gp463-win32-setup.exeを使ってインストールしたも のを利用しています。(ver.4.6.5でも大丈夫です) コマンドラインでgnuplotが実行できるように、インストールされたgnuplot.exeがあるディレクトリへあらかじめPathを通しておきます。
Clojureは、1.6.0をダウンロードしました。 Getting Startedにあるように、
java -cp clojure-1.6.0.jar clojure.main
で、REPLを起動して利用しています。
以下が、そのスクリプトですが、 プロセスを開始するgpstart、gnuplotのコマンドを送るgpdo、 終了するgpstopという関数を作っています。 sin(x)をプロットするのは、demo関数で行います。
(defrecord GnuplotProc [proc out in])
(defn gpstart
"Start gnuplot process"
[]
(let [proc (.start (doto (ProcessBuilder. '("gnuplot" "--persist"))
(.redirectErrorStream true)))
out (clojure.java.io/writer (.getOutputStream proc))
in (clojure.java.io/reader (.getInputStream proc))]
(GnuplotProc. proc out in)))
(defn gpstop
"Stop gnuplot process"
[proc]
(.destroy (get proc :proc)))
(defn gpdo
"send command string to gnuplot process"
[proc s]
(let [w (get proc :out)]
(.write w (str s))
(.newLine w)
(.flush w)))
(defn demo
"Demo function"
[]
(def p (gpstart))
(gpdo p "set xlabel \"x\"")
(gpdo p "set ylabel \"y\"")
(gpdo p "plot sin(x)")
(read)
(gpstop p))
(demo)
clispと、pythonでも書いてみました。(defun gpstart
;Start gnuplot process
()
(make-pipe-io-stream "gnuplot --persist" :buffered t))
(defun gpstop
;Stop gnuplot process
(proc)
(let ()
(gpdo proc "quit")
(close proc)))
(defun gpdo
;send command string to gnuplot process
(proc s)
(let ()
(format proc "~A~%" s)
(force-output proc)))
(defun demo
;demo function
()
(let ((p (gpstart)))
(gpdo p "set xlabel \"x\"")
(gpdo p "set ylabel \"y\"")
(gpdo p "plot sin(x)")
(read)
(gpstop p)))
(demo)
Pythonで書いたスクリプトは以下の通り。
import subprocess
def gpstart():
""" Start gnuplot process """
proc = subprocess.Popen(["gnuplot", "--persist"],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
return proc
def gpstop(proc):
""" Stop gnuplot process """
gpdo(proc, "quit")
proc.kill()
def gpdo(proc, s):
""" send command string to gnuplot process """
proc.stdin.write(s)
proc.stdin.write("\n")
proc.stdin.flush()
def demo():
""" Demo function """
p = gpstart()
gpdo(p, 'set xlabel "x"')
gpdo(p, 'set ylabel "y"')
gpdo(p, 'plot sin(x)')
raw_input()
gpstop(p)
if __name__ == '__main__':
demo()
この程度なら、行数はほぼ一緒ですね。clispやClojureを使ってもgnuplotを操作できそうなので、ひと安心です。
Rubyでもやってみました。
def gpstart
# Start gnuplot process
IO.popen("gnuplot --persist", "r+")
end
def gpstop(io)
# Stop gnuplot process
io.close
end
def gpdo(io, s)
# send command string to gnuplot process
io.puts(s)
end
def demo
io = gpstart
gpdo(io, "set xlabel \"x\"")
gpdo(io, "set ylabel \"y\"")
gpdo(io, "plot sin(x)")
gets
gpstop(io)
end
if __FILE__ == $0
demo
end
シンプルですね。Windows環境でirbを利用する人は少ないのかな。 ActiveScriptRuby 2.1.2-p95を利用してみたのですが、 irbのインタラクティブな環境で、Backspaceがちゃんと動作しませんでした。 検索してみたら、1.9.2での同様な症状と対処法がこちらにありました。 irbに--noreadlineオプションをつけて起動すると、正常にBackspaceできるようになりました。
2016/07/24追記
同じものをC言語で。Windows Vista 32bit MinGWのgcc-4.9.3で確認。
#include
FILE *gpstart(void);
void gpstop(FILE *p);
void gpdo(FILE *p, char *s);
FILE *gpstart(void) {
/* start gnuplot process */
return popen("gnuplot.exe --persist", "w");
}
void gpstop(FILE *p) {
/* stop gnuplot process */
gpdo(p, "quit");
pclose(p);
}
void gpdo(FILE *p, char *s) {
/* send command string to gnuplot process */
fprintf(p, s);
fprintf(p, "\n");
}
void demo(void) {
/* demo function */
FILE *p;
p = gpstart();
gpdo(p, "set xlabel \"x\"");
gpdo(p, "set ylabel \"y\"");
gpdo(p, "plot sin(x)");
gpstop(p);
}
void main(void) {
demo();
}
0 件のコメント:
コメントを投稿