# Converting x,y pairs to an image: alternative to Histogram3D for sparse data?

I have a list of {x, y} integer pairs representing single events in pixel coordinates in the {x, y} plane, with occasional duplicates. I'd like to convert that list into an image. There are only a few thousand {x,y} pairs, but the x y space is large, 1k x 1k, so Histogram3D[XYlist, {xpixels, ypixels}] is very slow. Is there a simple command to convert this list into a 2d array (or an image)? For example, with only 4 points:

coords = {{1, 4}, {2, 5}, {1000, 300}, {250, 300}}
Histogram3D[coords, {1000, 1000}]

This returns a graphical histogram after some time. I'd like a 2d array or image. Maybe use HistogramList somehow?

I'm hoping there's a better way than defining a 2d constant array and looping through the list of points to populate it, incrementing the pixel value for each hit.

• You want a 2D array representing the number of events at a certain pixel {x, y}? Commented Nov 14, 2015 at 0:18
• @march thank you, yes a 2D array, in this case 1000 x 1000, the value of each element representing the number of events at that pixel. (so in this case most values would be 0). Commented Nov 14, 2015 at 0:26
• I've got an answer for you, I think, that will be very fast. Hold on a sec. Commented Nov 14, 2015 at 0:26

Try this. We'll use as a sample list

list = RandomInteger[{1, 100}, {1000, 2}];

This is a list of 1000 pixels positions, where x and y go from 1 to 100. We first Tally, which counts the repeats, turn each tally into a Rule that we feed to SparseArray to generate the array, then use ArrayPlot. You will need to tell SparseArray the number of pixels in each direction. In this case, the image is 100 by 100 pixels. In your case, replace 100 by 1000 pixels.

ArrayPlot[SparseArray[Rule @@@ Tally@list, {100,100}]]

Could also use MatrixPlot:

MatrixPlot[SparseArray[Rule @@@ Tally@list, {100,100}]]

• This works very efficiently! Excellent solution @march It also preserves the absolute coordinates (I was worried it might shift everything so the first event moved to 0,0 ) Great! Commented Nov 14, 2015 at 0:39

You can use SparseArray directly with the option "TreatRepeatedEntries" -> 1 (ref):

list = RandomInteger[{1, 1000}, {10000, 2}];

SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> 1}];

s = SparseArray[
list -> ConstantArray[1, Length@list], {1000, 1000}]; // AbsoluteTiming
(* {0.001821, Null} *)

s // ArrayPlot

It is the most efficient approach to obtain histogram (and weighted histogram as well) on sparse data.

• Yes this is even faster and gets the intended result. (Without TreatRepeatedEntries->1 it gives a binary image; I would certainly never have stumbled across this solution!) The Stackexchange community is wonderful! Commented Nov 16, 2015 at 18:36