views:

105

answers:

2

I'm looking for a way to visualize a 2d java array that's being updated in a simulation written in clojure the same way I would use imshow in matplotlib to visualize a numpy array.

What's the best way to do this? Alternatively I could save the arrays to disk and visualize it in matplotlib. What would be the best way to go about that?


Here's my attempt based on the Java code here, but making the BufferedImage really slow. Is there any way to speed it up?:

(import 
 '(java.awt Color Graphics Graphics2D Dimension GradientPaint BorderLayout)
 '(java.awt.image BufferedImage)
 '(javax.swing JPanel JFrame))

(def L 1024)

(def image (BufferedImage. (* L 1) (* L 1) (. BufferedImage TYPE_INT_RGB)))
(def g2 (. image createGraphics))

(defn get-color-map []
  (let [STEPS 100
        colormap (BufferedImage. STEPS 1 (BufferedImage/TYPE_INT_RGB))
        g (.createGraphics colormap)
        paint (GradientPaint. 0 0 (Color/RED) STEPS 0 (Color/GREEN))
        ]
    (doto g
      (.setPaint paint)
      (.fillRect 0 0 STEPS 1))
    colormap))

(defn get-color [x start finish colormap]
  (let [y (/ (- x start) (- finish start))
        STEPS 100]
    (Color. (.getRGB colormap (int (* y STEPS)) 0))))

(defn fill-image [^"[[D" arr ^Graphics2D g sideX sideY ^BufferedImage colormap]
  (dotimes [i (alength arr)]
    (dotimes [j (alength ^"[D" (aget arr 0))]
       (doto g
         (.setColor (get-color (aget ^"[[D" arr (int i) (int j)) -10.0 10.0 colormap))
         (.fillRect (int (* i sideX)) (int (* j sideY)) sideX sideY)))))


(def panel
     (doto (proxy [JPanel] []
             (paintComponent [g] (.drawImage g image 0 0 nil)))))

(def frame
     (doto (JFrame. "Heat Map")
       (.add panel BorderLayout/CENTER)
       (.pack)
       (.setLocationRelativeTo nil)
       (.setVisible true)))

And here's an attempt using processing from incanter. It's also pretty slow:

(let [sktch (sketch
             (setup []
                    (doto this
                      ;no-loop
                      (size 1024 1024)
                      (framerate 15)
                      smooth))

              ;; define the draw function
              (draw []
                    (def A (gaussian-matrix 1024 0 1))
                    (dotimes [i 1024]
                      (dotimes [j 1024]
                        (doto this
                          (stroke (int (abs (* (aget A i j) 255))))
                          (point i j))))))]

  (view sktch :size [1024 1024]))
A: 

its not a full equivalent though you perhaps the Pretty Printer Library will get you started:

 (pprint (for [x (range 10)] (range x)))         
(()
 (0)
 (0 1)
 (0 1 2)
 (0 1 2 3)
 (0 1 2 3 4)
 (0 1 2 3 4 5)
 (0 1 2 3 4 5 6)
 (0 1 2 3 4 5 6 7)
 (0 1 2 3 4 5 6 7 8))
nil

This is not on hte same scale as imshow (being text only) so i'm really suggesting that it is something you may want to use until you find something prettier.

Arthur Ulfeldt
I'm really looking to visualize a square array with ~1 million pixels that's changing in time. But this will be useful for me in checking the output of my functions as I build up the simulation. Thanks.
Ranjit
+1  A: 

Use Octave's java package to get the Java object into Octave, then call Octave's imshow.

Jouni K. Seppänen