1 local Histogram = setmetatable({}, {__call=function(self,options)
2 local h = setmetatable({},{__index=self})
7 function Histogram:init(options)
9 self.size = options.size
11 for _,entry in ipairs(options.data) do
12 local x, count = unpack(entry)
17 for _,entry in ipairs(options.data) do
18 local x, count = unpack(entry)
20 if not iqrMin and t >= .25*total then iqrMin = x end
21 if not iqrMax and t >= .75*total then iqrMax = x end
23 local h = 2*(iqrMax-iqrMin)*total^(1/3)
24 local xmin, xmax = options.xmin or options.data[1][1], options.xmax or options.data[#options.data][1]
25 local numBuckets = options.numBuckets or math.max(3, math.min(options.size.x/10, math.ceil((xmax - xmin) * total / h)))
31 for _,entry in ipairs(options.data) do
32 local x, count = unpack(entry)
33 local b = 1 + math.floor((x - xmin)/(xmax - xmin) * (numBuckets-1))
34 buckets[b] = (buckets[b] or 0) + count
35 ymax = math.max(buckets[b], ymax)
39 self.buckets = buckets
41 return self.pos.x + self.size.x * (x-xmin)/(xmax-xmin)
45 function Histogram:fromList(list, options)
48 for _,x in ipairs(list) do
49 if not data[#data] or data[#data][1] ~= x then
50 table.insert(data, {x,1})
52 data[#data][2] = data[#data][2] + 1
56 return Histogram(options)
59 function Histogram:draw()
60 local height = self.size.y / (#self.buckets-1)
61 for i,count in ipairs(self.buckets) do
63 local width = count/self.ymax * self.size.x
64 love.graphics.rectangle('fill', self.pos.x,
65 self.pos.y+(#self.buckets-i-1)*height, width, height)