haskell で gnuplotを利用する + 利用したときの個人的な詰まりどころ
gnuplot: 2D and 3D plots using gnuplot を利用してみた
だいたい以下のページの感じで出来る.
ただし今回はもうチョット踏み込んだことをやってみる。
用意
gnuplot等の用意は上記のページを見て欲しい。
haskellのライブラリとしてのgnuplotはstack
で準備できるので、プロジェクト.cabal
にgnuplotを追記したら良い
library hs-source-dirs: src exposed-modules: Lib build-depends: base >= 4.7 && < 5 , gnuplot default-language: Haskell2010
で、stack build
したら怒られるはずなので、 stack solver
とか stack build --modify-stack-yml
とかを叩いてやれば良い
棒グラフのサンプル
module Lib ( someFunc ) where import Graphics.Gnuplot.Simple someFunc :: IO () someFunc = do plotPathStyle [(Title "Frequency"), (XTicks (Just ["('hoge' 0, 'huga' 1, 'piyo' 2)"]))] (defaultStyle{plotType = Boxes }) [(0::Int,0), (1,1), (2,2)]
stack ghci > someFunc
以上で実行可能
スタイルはデフォルトのまま
gnuplotで出来ることとしてはもうちょいいい感じに出来るはずだけど、 もう少しきれいにやるなら Graphics.Gnuplot.Advances
を使う必要がある。
詰まりどころ1
まず注意しなければならないのが、 おそらく GHCiからでないと利用できない様子. ドキュメントにGHCiかHugsから使えるよって書いてある.
少なくとも自分の環境ではコンパイルが上手く行った後のバイナリを動作させても、gnuplotが起動することは無かった。
ただしstackの環境であれば、 stack ghci
を実行すると src/Lib.hs
のモジュールを読み込む設定が最初から書かれているので、 コードを書いてghciから実行させる形で妥協したら良いと思う。
詰まりどころ2
ghciから実行させるのは良いが、gnuplot自体はおそらく非同期でコードが実行される。 非同期で実行されるから、間違ったコードで死んでるのか、処理中なのかわかりづらい。
具体的には遅延評価される重めのlistをgnuplotに突っ込もうとすると、動いているのかどうかよくわからない問題が発生する. (自分は1~2日気づかなかった)
そんなときはtopコマンドを見れば良い。
Processes: 332 total, 3 running, 329 sleeping, 1548 threads 00:29:13 Load Avg: 1.97, 2.12, 2.08 CPU usage: 13.71% user, 1.45% sys, 84.83% idle SharedLibs: 174M resident, 43M data, 48M linkedit. MemRegions: 67643 total, 5202M resident, 175M private, 3489M shared. PhysMem: 16G used (2002M wired), 22M unused. VM: 1930G vsize, 627M framework vsize, 0(0) swapins, 0(0) swapouts. Networks: packets: 256919/208M in, 222563/26M out. Disks: 870239/13G read, 162387/6235M written. PID COMMAND %CPU TIME #TH #WQ #PORT MEM PURG CMPRS PGRP PPID STATE BOOSTS %CPU_ME %CPU_OTHRS UID FAULTS COW MSGSENT MSGRECV SYSBSD SYSMACH CSW PAGEINS IDLEW POWER 12713 ghc 99.8 00:17.90 5/1 0 14 1778M 0B 0B 12700 12700 running *0[1] 0.00000 0.00000 501 525572 1375 70 34 150746+ 3997 15304+ 59 316 99.8
ghcがCPU利用率100%で張り付いているって言うことは、裏で頑張って処理しているんだな。ってことが分かる