数値を得たら、プロットしてみるということはしばしばあります。 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 件のコメント:
コメントを投稿