I'm trying to generate a histogram for a large data set with the following lines of code:
MaxSideLength = Ceiling[Max[data]];
Export["Histogram.png",
Image[ArrayPlot[HistogramList[data, {1, MaxSideLength, 1}][[2]],
ColorRules -> {0 -> Black, 1 -> Red, 2 -> Yellow}], ImageSize -> MaxSideLength]];
Where ImageMatrix has something like $O(10^6)$ datapoints and I want to have maybe $50,000 \times 50,000$ bins (where each bin corresponds to a pixel in the output PNG image).
Unfortunately, my memory usage goes through the roof with the above script (exhausting over 200 GB of RAM). I can pull off having maybe $20{\rm k} \times 20{\rm k}$ bins, but anything above this fails.
Is there a more efficient way to proceed? If need by, I can properly round all of the values in data.
I know this comparison is unfair, but given that the typical output size for a $20,000 \times 20,000$ pixel output PNG is something like 40 Mb, it seems a little odd to me that the binning and image creation process would require over $2500x$ the memory in RAM.
Ok, let's run a little analysis script provided by ssch:
mmu = MaxMemoryUsed[];
n = 20*10^6;
{w, h} = {5000, 5000};
data = RandomVariate[NormalDistribution[], {n, 2}];
bins = BinCounts[data,
{Min[data], Max[data], (Max[data] - Min[data])/w},
{Min[data], Max[data], (Max[data] - Min[data])/h}];
i = Image[bins /. {0 -> {0, 0, 0}, 1 -> {1, 0, 0}, 2 -> {1, 1, 0},
3 -> {0, 0, 1}, _?IntegerQ -> {1, 1, 1}}];
mmu2 = MaxMemoryUsed[];
mmu2 - mmu
The result for my value of n
is $\approx 600*10^6$. Increasing n
by an order of magnitude to $20*10^7$ yields a memory usage of $\approx 12*10^9$, however, if we run the script again, overwriting the "data" data structure, the memory usage reported is again only $\approx 600*10^6$.
However, if we increase the bin sizes to {w, h} = {10000, 10000}
, the memory usage jumps to $\approx 3.5*10^9$ (for the first run), and then oddly $\approx 2.5*10^9$ for subsequent runs (since I suppose we're overwriting previous data structures). My conclusion is that an increase in the number of bins is responsible for the blowup in RAM usage.
Export
,Image
orArrayPlot
you see the high memory usage? How does something liken = 1000000; {w, h} = {5000, 5000}; data = RandomVariate[NormalDistribution[], {n, 2}]; bins = BinCounts[data, {Min[data], Max[data], (Max[data] - Min[data])/w}, {Min[data], Max[data], (Max[data] - Min[data])/h}]; i=Image[bins /. {0 -> {0, 0, 0}, 1 -> {1, 0, 0}, 2 -> {1, 1, 0}, 3 -> {0, 0, 1}, _?IntegerQ -> {1, 1, 1}}];
behave memory-wise? $\endgroup$ArrayPlot
, causing it to eat up a LOT of memory $\endgroup$