I want to align my x-axis labels in Incanter's histogram (based on JFreeChart) so that they are centered under the bars. I also want to get rid of the fractional axis tick marks.
My question is very similar to JFreeChart: Aligning domain axis with histogram bins.
Here are related questions for other languages:
R: Align bars of histogram centered on labels
Python: How to center labels in histogram plot
(require '[incanter.charts :refer [histogram]])
(require '[incanter.core :refer [view]])
(def data [1 1 1 1 3 6])
(view (histogram data))
P.S. The histogram is also unappealing in that the bar for 6 is to the left of the tick mark. The other bars are to the right of their tick marks!
Update: See also:
Relevant, but I don't see a solution here: How to center bars on tick marks
Based on reviewing the Incanter source code and the JFreeChart documentation, I don't believe that org.jfree.chart.ChartFactory/createHistogram exposes the functionality to customize the axis. (I could be wrong -- perhaps you can modify the axis after using that factory method.)
In any case, I found it easier (and perhaps necessary) to use the bar-chart directly:
(ns custom-incanter
(:require
[incanter.charts :as ic]
[incanter.core :as i]))
(defn hist
[values title]
{:pre [(sequential? values)]}
(let [freq (frequencies values)
f #(freq % 0)
ks (keys freq)
a (apply min ks)
b (apply max ks)
x-values (range a (inc b))
x-labels (map str x-values)
y-values (map f x-values)]
(i/view (ic/bar-chart x-labels y-values :title title))))
Use it like this:
(hist [1 1 1 1 3 6] "Using Bar Chart")
Related
If I create a new project with
lein new quil foo
then reduce the src/foo/core.clj to
(ns foo.core
(:require [quil.core :as q]
[quil.middleware :as m]))
(defn draw [state]
(if (< (rand) 0.5)
(q/line 0 0 500 500)
(q/line 0 500 500 0)))
(q/defsketch foo
:title "Try this at home"
:size [500 500]
:draw draw
:features [:keep-on-top]
:middleware [m/fun-mode])
and evaluate the program in lein repl with (use 'foo.core), both lines are drawn (i.e. I get a big X). (if (< (rand) 0.5) true false) works as expected, so what am I missing?
Presumably draw is called many times - it wouldn't be a very interactive framework if it only drew the screen once! Some of those times, you randomly choose to draw one line, and sometimes the other; and you never erase either. As a result, both of them are visible on the screen.
I am a beginner to functional programming and Clojure programming language and I'm resorting to recur pretty much for everything. I have a dataset in csv, imported as a map. I have extracted the info I need to use as vectors. Each column is a vector [1 5 10 8 3 2 1 ...] and I want to calculate the mean of each column. I wrote the following function:
(defn mean
"Calculate the mean for each column"
([columns]
(mean columns []))
([columns
means]
(if (empty? columns)
means
(recur (rest columns)
(conj means (float (/ (reduce + (first columns)) (count (first columns)))))))))
;; Calcule the mean for the following vectors
(mean [[1 2 3] [1 2 3] [1 2 3]])
; => [2.0 2.0 2.0]
Is this a functional way of solving this problem?
I'd break it down a little farther and use map instead of for. I personally like having many, smaller functions:
(defn mean [row]
(/ (apply + row) (count row)))
(defn mean-rows [rows]
(map mean rows))
But this is the same general idea as #Alan's answer.
The way you're doing it is already considered "functional". It should be said though that while using recur is good, usually you can achieve what you need more easily using reduce, or at least map. These options eliminate the need for explicit recursion, and generally lead to simpler, easier to understand code.
Here is a simple answer:
(defn mean
"Calculate the mean of each column"
[cols]
(vec ; this is optional if you don't want it
(for [col cols]
(/ ; ratio of num/denom
(reduce + col) ; calculates the numerator
(count col))))) ; the number of items
(mean [[1 2 3] [1 2 3] [1 2 3]]) => [2 2 2]
If you haven't seen it yet, you can get started here: https://www.braveclojure.com/
I recommend buying the printed version of the book, as it has more than the online version.
I have this small game world state, something like the following:
(defn odds [percentage]
(< (rand-int 100) percentage))
(defn world []
{:entities []})
(defn make-bird []
{:pos [(rand-int 100) (rand-int 100)]
:age 0
:dir (vec/dir (rand (. Math PI)))})
(defn generate-entities [entities]
(if (odds 10)
(conj entities (make-bird))
entities))
(defn update-entity [entity]
(-> entity
(update :pos (partial vec/add (:dir entity)))
(update :age inc)))
(defn update-entities [entities]
(vec (map update-entity entities)))
(defn old? [{age :age}]
(> age 10))
(defn prune-entities [entities]
(vec (filter #(not (old? %)) entities)))
(defn update-world [world]
(-> world
(update :entities generate-entities)
(update :entities update-entities)
(update :entities prune-entities)))
So update-world goes through three steps. First there's a 1/10 chance of generating a new bird entity, which flies in a random direction. Then it updates all birds, updating their position and incrementing their age. Then it prunes all old birds.
I use this same technique for generating particles systems. You can do fun stuff like (iterate update-world (world)) to get a lazy list of world states which you can consume at whatever frame rate you want.
However, I now have a game world with autonomous entities which roam around and do stuff, kind of like the birds. But I want to get a textual representation of what happened when evaluating update-world. For example, update-world would ideally return a tuple of the new world state and a vector of strings - ["A bird was born at [12, 8].", "A bird died of old age at [1, 2]."].
But then I really can't use (iterate update-world (world)) anymore. I can't really see how to do this.
Is this something you'd use with-out-string for?
If you want to enhance only your top-level function (update-world) in your case you can just create a wrapper function that you can use in iterate. A simple example:
(defn increment [n]
(inc n))
(defn logging-increment [[_ n]]
(let [new-n (increment n)]
[(format "Old: %s New: %s" n new-n) new-n]))
(take 3 (iterate logging-increment [nil 0]))
;; => ([nil 0] ["Old: 0 New: 1" 1] ["Old: 1 New: 2" 2])
In case you want to do it while collecting data at multiple level and you don't want to modify the signatures of your existing functions (e.g. you want to use it only for debugging), then using dynamic scope seems like a reasonable option.
Alternatively you can consider using some tracing tools, like clojure/tools.trace. You could turn on and off logging of your function calls by simply changing defn to deftrace or using trace-ns or trace-vars.
There are two potential issues with using with-out-str
It returns a string, not a vector. If you need to use a vector, you'll need to use something else.
Only the string is returned. If you are using with-out-str to wrap a side-effect (e.g., swap!), this might be fine.
For debugging purposes, I usually just use println. You can use with-out if you want control over where the output goes. You could even implement a custom stream that collects the output into a vector of strings if you wanted. You could get similar results with a dynamically bound vector that you accumulate (via set!) the output string (or wrap the vector in an atom and use swap!).
If the accumulated vector is part of the computation per se, and you want to remain pure, you might consider using a monad.
What about using clojure.data/diff to generate the string representation of changes? You could do something like this:
(defn update-world [[world mutations]]
(let [new-world (-> world
(update :entities generate-entities)
(update :entities update-entities)
(update :entities prune-entities))]
[new-world (mutations (clojure.data/diff world new-world))]))
Then you could do something like (iterate update-world [(world) []]) to get the ball rolling.
I have the following ClojureScript code and am trying to detect the coordinates of a a click. So far, I can't even get Javascript alerts to recognize a click, let alone give me the coords.
I know I will have to write a function to have it give me the exact cells being clicked, but as a start, need to know how to get the coordinates of any area clicked on a page.
Thanks!
(defn header [color text]
[:h1
{:style
{:color color
:background-color "blue"}}
text])
(defn Cell []
[:div
{:style
{:width "40px"
:height "40px"
:float "right"
:margin-bottom "1px"
:margin-right "1px"
:background-color "grey"
:border "1px" "solid" "white"}}])
(defn home-page []
[:div
[header "red" "Minesweeper"]
[:div
{:style
{:width "440px"
:height "440px"}}
(repeat 100 [Cell])]])
Put an :onClick key at the same map indentation level as the :style. Its value should be a function, which will get an event e. Then:
(let [coords (.getClientPosition e)
coords' {:x (aget coords "x")
:y (aget coords "y")}])
Here's an example of a hashmap that has an :onClick event and its function:
{ :href "#"
:onClick (fn [e]
(.preventDefault e)
(swap! counter inc))}
The only thing that matters in the above is getting the e and using it. That was taken from the flappybird example program, which is how I got started.
Does anyone know how to display an incanter chart to jpanel without reverting to jfreechart?
An Incanter chart is a JFreeChart under the hood so it's impossible to avoid the JFreeChart library altogether.
However, if you just want to include an incanter chart inside a Panel that you can use in a normal Swing application then there is a ready-made class called org.jfree.chart.ChartPanel which can do this for you.
Example code:
(ns my.chart
(:import [org.jfree.chart ChartPanel])
(:import [java.awt Component Dimension])
(:import [javax.swing JFrame])
(:use [incanter core stats charts]))
(defn show-component [^Component c]
"Utility Function to display any Java component in a frame"
(let [^JFrame frame (JFrame. "Test Window")]
(doto frame
(.add c)
(.setSize (Dimension. 640 480))
(.setVisible true))))
(show-component (ChartPanel. (function-plot sin -10 10)))