Category Archives: Clojure

Incanter has migrated to Leiningen

I have completed the process of migrating Incanter from the Maven build tool to Leiningen.

Incanter now includes several project.clj files, one for the overall project and one for each submodule. The top-level project.clj file builds what was formerly called incanter-app/incanter-full using the modules incanter-core, incanter-charts, incanter-processing, incanter-io, incanter-pdf, and incanter-mongodb.

The modules live in the modules/ directory, and each is an independent Leiningen project that can be built as a standalone library.

The script/ directory has repl and swank scripts (both sh and bat) stolen from labrepl, and simple scripts for managing the builds of all the modules (install, test, clean).

One bonus of this change is that I have been able to push Incanter and its modules back on to Clojars.org.

To include the full library as a dependency in your Leiningen project, add the following entry to your project.clj file:

[incanter "1.2.1-SNAPSHOT"]

If you only want to include a subset of Incanter’s functionality in your project, use one of the following modules instead:

 [incanter/incanter-core "1.2.1-SNAPSHOT"]
 [incanter/incanter-charts "1.2.1-SNAPSHOT"]
 [incanter/incanter-io "1.2.1-SNAPSHOT"]
 [incanter/incanter-processing "1.2.1-SNAPSHOT"]
 [incanter/incanter-pdf "1.2.1-SNAPSHOT"]
 [incanter/incanter-mongodb "1.2.1-SNAPSHOT"]

Updated build instructions can be found in the new README available in Incanter’s Github repository.

Dynamic data tables with Incanter

In a previous post, Dynamic charts with Incanter, I demonstrated how sliders can be linked to either an xy-plot or a scatter-plot. In this post I’ll demonstrate how sliders can be used to manipulate a dataset query, and dynamically update the results in a table.

Start by using the get-dataset function to load the iris sample data. Next, create a Swing JTable object containing the data with the data-table function, and then view it.

(use '(incanter core charts datasets))

(let [data (get-dataset :iris)
      table (data-table data)]
  (view table)

Use the sliders macro to create two sliders; one bound to species, a vector of iris species values, and the other bound to min-petal-length, a range of petal-lengths that will provide the lower bound for a query, and then create the expression that will be evaluated when the sliders are manipulated.

  (sliders [species ["setosa" "virginica" "versicolor"]
            min-petal-length (range 0 8 0.1)]
    (set-data table ($where {:Species species 
                             :Petal.Length {:gt min-petal-length}} 
                            data))))

In this case, the expression uses the set-data multi-method to update the values of the data-table with the results from a $where query.

Manipulating the sliders changes the query values, and dynamically updates the rows in the table.

Although it would be more natural to use a drop-down option menu, check-boxes, or radio-buttons to manipulate the species values, this example demonstrates that non-numeric values can be bound to sliders.

The data-table function and set-data multi-method are available in the latest version of Incanter on Github and on repo.incanter.org.

Getting started with Incanter using labrepl

Stuart Halloway created a great Clojure tutorial and development environment for the PragmaticStudio Clojure workshop called labrepl, which is available on Github. A nice feature of labrepl is that is comes with several Clojure libraries, including Clojure-contrib, Compojure, and Incanter. It also includes scripts for starting a Clojure REPL and/or Swank server, and instructions for setting up several different IDEs for Clojure development.

In addition to starting a REPL, the included repl script starts a webserver, on port 8080, that includes several Clojure lab exercises and solutions.

It’s a great way to get started with Clojure and Incanter, so check it out. And if you’re an experienced Clojure programmer, Stuart is looking for contributors to create additional labs, so pitch in if you can. I plan to begin by creating some labs covering the material in my Incanter charts and datasets presentation.

Dynamic charts with Incanter

I had the opportunity to attend last week’s PragmaticStudio Clojure workshop taught by Rich Hickey and Stuart Halloway (I highly recommend it, and there are still seats open for the May class). During the three days I talked with Rich about features he’d like to see in Incanter, and the first thing he asked about was adding dynamic charts, like are available in Mathematica using the Manipulate function. So I ended up spending much of my lab time working on this feature, the first draft of which is now available.

Incanter has three new macros, sliders, dynamic-xy-plot, and dynamic-scatter-plot. The sliders macro can bind multiple named sequences to an equal number of JSlider widgets. When a slider is manipulated a user defined expression is evaluated. For instance, the following code will display two slider widgets bound to two sequences, x and y.

(sliders [x (range -3 3 0.01)
          y (range 0.01 10 0.1)]
  (foo x y))
  

Each time one of the sliders is manipulated the expression (foo x y) will be evaluated with the new value of either x or y. Presumably, foo has side effects, like changing the value of a ref or manipulating a GUI widget, since it is running in the separate thread used by the slider widget.

I then combined this macro with incanter.charts/set-data function to create dynamic versions of xy-plot and scatter-plot, named appropriately dynamic-xy-plot and dynamic-scatter-plot respectively.

The following example creates an xy-plot of a sequence of values named x versus the normal PDF of x, and displays two sliders bound to the mean and standard deviation of the PDF.

(let [x (range -3 3 0.1)]
  (view (dynamic-xy-plot [mean (range -3 3 0.1)
                          std-dev (range 0.1 10 0.1)]
          [x (pdf-normal x :mean mean :sd std-dev)])))

The expression provided to dynamic-xy-plot must produce a sequence containing either two sequences with N values, or N sequences with two values each. In other words, a N-by-2 matrix or a 2-by-N matrix, where N is the number of points plotted. The expression above,

[x (pdf-normal x :mean mean :sd std-dev)]

produces a vector containing a sequence called x and the sequence produced by calling pdf-normal on x (equivalent to a N-by-2 matrix).

Manipulating the sliders will change the shape and position of the curve.

The dynamic-scatter-plot macro works the same way as dynamic-xy-plot. All three macros are available in the version of Incanter on Github and in repo.incanter.org.

Incanter blog post roundup

There have been several cool blog posts over the last few weeks featuring Incanter that I would like to highlight here.

Incanter code repository

It’s been a long time coming, but Incanter is available in a public code repository (http://repo.incanter.org) once again.

The version available in the Clojars repository has grown increasingly out of date, but couldn’t be updated due to Incanter’s new modular build structure; a structure that lets developers include only the subset of Incanter functionality that they need.

For instance, if you only need the functionality found in incanter.core and incanter.stats, then include the incanter-core dependency in your project.clj file. If you need charts but, not Processing visualizations, include incanter-charts. If you want access to the incanter.chrono library, but nothing else, use the incanter-chrono dependency.

Instructions for building Leiningen-based projects using the repository are available on the Incanter repo’s homepage, http://repo.incanter.org.

Data Sorcery with Clojure & Incanter: Introduction to Datasets & Charts

I put together my slides (pdf) for next week’s National Capital Area Clojure Users Group February Meetup. Being snow-bound this week, I’ve been able to make more slides than I’ll have time to cover during next week’s session, so I’ll be skimming over some of the examples.

Russ Olsen will start the session with an introduction to Clojure, so if you’re in the D.C. area next Thursday (February 18), sign-up for the meetup.

The code used in this presentation is available here, and a more printer-friendly version of the presentation itself, with a white background, is available here.