在Clojure中绘制两个列表

时间:2018-10-02 13:30:24

标签: clojure

我有两个列表。例如:列表A为[1 2 3 2 2 1],列表B为[1.2 2.2 1 1 1 1]。我想在x轴上具有列表A的唯一编号以及列表B中相应条目的总和。例如:对于上面的示例,我想绘制{(1,2.2),(2,4.2), (3,1)}作为直方图(而不是散点图)。

我的要求涉及两个步骤。

  1. 首先对列表A中的每个唯一值对列表B中的值求和
  2. 将这些和相对于列表A中的对应值绘制为直方图。

能帮我吗?

编辑: 这是我的尝试,基于我从阅读SO上的其他答案中学到的一点知识:

(def A [1 2 3 2 1])
(def B [1.2 2.3 2 1 1])
(for [x (distinct A)] (map first 
           (filter #(= (second %) x)
                   (map-indexed vector A))))
;; This gives the indices for each unique element in A
;; In this case, it gives ((0 4) (1 3) (2))

我无法弄清楚如何从列表B中获取相应的总和。我尝试了以下操作,但它不起作用。

(apply nth B (map first 
           (filter #(= (second %) 1)
                   (map-indexed vector A))) )
;; In this case, it gives on the first element i.e. 1.2

如您所见,我是Clojure和函数式编程语言的新手。您能指出一些解决类似问题的例子吗?

先谢谢了。

编辑: 第一项任务的最终解决方案:

(for [x (distinct A)]     (reduce + 0.0 (map #(nth B %) (map first 
               (filter #(= (second %) x)
                       (map-indexed vector A))) )  )         )
    ;; This gives me the correct output (2.2 3.3 2.0)

P.S:我不理解使用(map #(nth B%)..的概念。我只是从其他示例中偶然发现了它。

1 个答案:

答案 0 :(得分:2)

对于第一个任务,我想这种方式会更简单:

(def A [1 2 3 2  2 1])
(def B [1.2 2.2 1 1 1 1])
(def C
  (reduce (partial merge-with +)
          (map hash-map A B))) ; Vector of key-values [{1 1.2} {2 2.2} ...]
; {1 2.2, 2 4.2, 3 1}

对于第二项任务,那里有许多图表库选项。我以clj-xchart为例:

(require '[com.hypirion.clj-xchart :as c])

(let [x-values (keys C)
      min-x (apply min x-values)
      max-x (apply max x-values)]
  (c/view
    (c/category-chart
      {"C" C}
      {:title "Example"
       :legend {:visible? false}
       :x-axis {:order (range min-x max-x)}
       :theme :ggplot2})))

最后的剧情:

Chart example