|
| 1 | +function simpleunicodehistogram(x::AbstractArray; nbins::Integer=10, plotwidth::Integer=30, showcounts::Bool=true, xlabel="", ylabel="") |
| 2 | + # Find bounds, round them nicely |
| 3 | + l, u = extrema(x) |
| 4 | + digitsneeded = ceil(Int, -log10(u-l))+1 |
| 5 | + l = floor(l, digits=digitsneeded) |
| 6 | + u = ceil(u, digits=digitsneeded) |
| 7 | + |
| 8 | + # Fill histogram |
| 9 | + dx = (u - l) / nbins |
| 10 | + histcounts = fill(0, nbins) |
| 11 | + @inbounds for i ∈ 1:length(x) |
| 12 | + index = ceil(Int, (x[i] - l) / dx) |
| 13 | + if 1 <= index <= nbins |
| 14 | + histcounts[index] += 1 |
| 15 | + end |
| 16 | + end |
| 17 | + binedges = range(l,u,length=nbins+1) |
| 18 | + |
| 19 | + # Print the histogram |
| 20 | + blocks = [" ","▏","▎","▍","▌","▋","▊","▉","█","█"] |
| 21 | + scale = plotwidth/maximum(histcounts) |
| 22 | + lowerlabels = string.(round.(binedges[1:end-1], digits=digitsneeded+ceil(Int,log10(nbins)-1))) |
| 23 | + upperlabels = string.(round.(binedges[2:end], digits=digitsneeded+ceil(Int,log10(nbins)-1))) |
| 24 | + longestlower = maximum(length.(lowerlabels)) |
| 25 | + longestupper = maximum(length.(upperlabels)) |
| 26 | + println(ylabel*"\n") |
| 27 | + for i=1:nbins |
| 28 | + nblocks = histcounts[i] * scale |
| 29 | + blockstring = repeat("█", floor(Int, nblocks)) * blocks[ceil(Int,(nblocks - floor(nblocks))*8)+1] |
| 30 | + println(" (" * lowerlabels[i] * " "^(longestlower - length(lowerlabels[i])) * |
| 31 | + " - " * upperlabels[i] * " "^(longestupper - length(upperlabels[i])) * |
| 32 | + "] " * blockstring * (showcounts ? " $(histcounts[i])" : "")) |
| 33 | + end |
| 34 | + println("\n" * " "^max(plotwidth÷2 + 6 - length(xlabel)÷2, 0) * xlabel) |
| 35 | +end |
0 commit comments