/var/log/study

つまり雑記

haskell で gnuplotを利用する + 利用したときの個人的な詰まりどころ

gnuplot: 2D and 3D plots using gnuplot を利用してみた

だいたい以下のページの感じで出来る.

d.hatena.ne.jp

ただし今回はもうチョット踏み込んだことをやってみる。

用意

gnuplot等の用意は上記のページを見て欲しい。

haskellのライブラリとしてのgnuplotstackで準備できるので、プロジェクト.cabalgnuplotを追記したら良い

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

以上で実行可能

スタイルはデフォルトのまま

f:id:yaaamaaaguuu:20170416002246p:plain

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%で張り付いているって言うことは、裏で頑張って処理しているんだな。ってことが分かる