macrosclojureincanter

How to use macro in clojure to view xy-plot with many lines?


I try to write macro that takes dataset as argument and views all data from dataset on single xy-plot. For example,i create dataset

(def test-data
 [["RECALL" "CAFE" "CLIPPERS"]
 [0 0 0]
 [14 15 13]
 [160 146 155]])

and write this

(defmacro figure
  [datas]
  (let [x `(range 0 (nrow ~datas)) y `(rest (:column-names ~datas))]
   `(let [datas# ~datas]
      (with-data datas#
        (doto
          (xy-plot ~x ($ (first (:column-names datas#))))
          ~@(map (fn [arg] `(add-lines ~x ($ ~arg ))) (eval y));;this line, wheh rest of columns have added to xy plot, get me a trouble
          view))))) 
(figure test-data)  

But has problem with eval in code. I think, that is not Clojure idiomatic way and this don't work in some cases. I've tried all sorts of wild tricks to get column names of dataset as evaluated argument, but this didn't work.

Does exists method to eval expression at macro-expand time in macro?


Solution

  • You don't need to use macro here. Plain function will do the job:

    (defn figure [data]
      (let [x (range (nrow data))
            [h & t] (:column-names data)]
        (with-data data
          (let [plot (xy-plot x ($ h))]
            (doseq [col-name t]
              (add-lines plot x ($ col-name)))
            (view plot)))))