[Chart] Heat map/image support

Ben Gamari bgamari.foss at gmail.com
Tue May 8 15:55:56 BST 2012

While Chart has managed to steal most of my work away from matplotlib,
one feature that I've been sorely missing is the ability to plot a 2D
heatmap[1]. Admittedly, matplotlib's approach (e.g. imshow) isn't the most
elegant (at least until a pending patch[2] is merged), but it works
fairly well for the majority of my tasks (generally plotting
two-dimensional histograms). I'm hoping to fill this void in Chart.

While I've written some preliminary code to produce a heatmap-ish plot
within the Chart framework, I'm struggling to find a nice interface for
this functionality. My first thought (option A) was the following,

        data HeatMap z x y = HeatMap { heat_map_values_ :: [(x,y,z)]
                                     , heat_map_cell_size_ :: (x,y)

Unfortunately, it seems that this isn't going to work so well as I can't
ensure that types x and y have a Num instance (for addition), meaning I
can't determine the cell bounds correctly (as I would need to pass the
cell_size through the PointMapFn before I have something I could add).

The next approach (option B) I came up with was to encode the bounds of
each cell in the values themselves,

        data HeatMap z x y = HeatMap { heat_map_values_ :: [((x,y), (x,y) ,z)] }

This fixes the above problem at the expense of far more verbose values.

The last option (option C) would be to use the approach taken by
matplotlib, viewing a heatmap as an image. This has the disadvantage of
requiring the user to ensure the image properly positioned and scaled on
the axes (although this could be wrapped) but avoids the costly task of
drawing each rectangular cell individually (which takes 12s on my
machine for a 500x500 cell map). Moreover, the aliasing which results
from each cell being an individual rectangle is avoided.

The current status of my code can be found here[3]. Currently I'm
leaning towards option B or C. That being said, I think image support
would be useful (perhaps from a Repa array?), even if it is decided that
this is not the proper way to handle heat-maps. Any opinions? Any
options I have yet to think of?

Lastly, after the interface issues have been decided and the code
settled a bit, I'd happy to submit the code for merge into
Chart-proper. Alternatively it could just remain as a separate
package. Are there any opinions as to the proper way to handle this?


- Ben

[1] http://matplotlib.sourceforge.net/examples/pylab_examples/multi_image.html
[2] https://github.com/matplotlib/matplotlib/pull/826
[3] https://github.com/bgamari/chart-histogram/tree/heatmap

More information about the Chart mailing list