行列をヒストグラムで描きたい!

例えば、

 1  2  3
 4  5  6
 7  8  9
10 11 12

というようなデータをgnuplotでグラフ化したい。

splot "data1" matrix with pm3d

で描画させるとこういう感じになる。

違う。違うんだ。離散値だからヒストグラムにして欲しいんだ。

つまり、3次元の棒グラフを描きたい.
このためにデータを加工する必要がある。そこで、加工するスクリプトを書いた。

(defun matrix-to-histogram (data)
  "行列をgnuplotで棒グラフとして描けるデータに加工する"
  (flet ((pos (n) ;(0 1 1 2 2 ... i i  ... (1- n) (1- n) n) なる系列
           (let (l)
             (push 0 l)
             (dotimes (a (1- n))
               #1=(push (1+ a) l)
               #1#)
             (push n l)
             (reverse l))))
    (let* ((xs (length (car data)))
           (ys (length data))
           (xp (pos xs))
           (yp (pos ys))
           (nd (let (l) ;a11 a11 a21 a21 ... an1 an1 a12 a12 ... ann ann なる系列
                 (dolist (y data (reverse l))
                   #2=(dolist (x y)
                        (push x l)
                        (push x l))
                   #2#))))
      (let (l)
        (dolist (y yp (reverse l))
          (push
           (let (ll)
             (dolist (x xp (reverse ll))
               (push (list x y (pop nd)) ll))) l))))))

次のように、行列をlispで扱いやすいように二重リストにして食わせて、出力はformatで整える。

(format t "~{~{~{ ~A~}~%~}~%~}"
  (matrix-to-histogram '((1 2 3) (4 5 6) (7 8 9) (10 11 12))))

長々と出力されるので、ファイルに書きだしてプロット。

splot "data2" with pm3d

大体こんな感じ。これで描きたかったものは、また明日。