Plots.jl/src/utils.jl
2015-09-16 15:08:50 -04:00

132 lines
3.2 KiB
Julia
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

calcMidpoints(edges::AbstractVector) = Float64[0.5 * (edges[i] + edges[i+1]) for i in 1:length(edges)-1]
doc"Make histogram-like bins of data"
function binData(data, nbins)
lo, hi = extrema(data)
edges = collect(linspace(lo, hi, nbins+1))
midpoints = calcMidpoints(edges)
buckets = Int[max(2, min(searchsortedfirst(edges, x), length(edges)))-1 for x in data]
counts = zeros(Int, length(midpoints))
for b in buckets
counts[b] += 1
end
edges, midpoints, buckets, counts
end
doc"""
A hacky replacement for a histogram when the backend doesn't support histograms directly.
Convert it into a bar chart with the appropriate x/y values.
"""
function histogramHack(; kw...)
d = Dict(kw)
# we assume that the y kwarg is set with the data to be binned, and nbins is also defined
edges, midpoints, buckets, counts = binData(d[:y], d[:nbins])
d[:x] = midpoints
d[:y] = float(counts)
d[:linetype] = :bar
d[:fillto] = d[:fillto] == nothing ? 0.0 : d[:fillto]
d
end
doc"""
A hacky replacement for a bar graph when the backend doesn't support bars directly.
Convert it into a line chart with fillto set.
"""
function barHack(; kw...)
d = Dict(kw)
midpoints = d[:x]
heights = d[:y]
fillto = d[:fillto] == nothing ? 0.0 : d[:fillto]
# estimate the edges
dists = diff(midpoints) * 0.5
edges = zeros(length(midpoints)+1)
for i in 1:length(edges)
if i == 1
edge = midpoints[1] - dists[1]
elseif i == length(edges)
edge = midpoints[i-1] + dists[i-2]
else
edge = midpoints[i-1] + dists[i-1]
end
edges[i] = edge
end
x = Float64[]
y = Float64[]
for i in 1:length(heights)
e1, e2 = edges[i:i+1]
append!(x, [e1, e1, e2, e2])
append!(y, [fillto, heights[i], heights[i], fillto])
end
d[:x] = x
d[:y] = y
d[:linetype] = :line
d[:fillto] = fillto
d
end
doc"""
A hacky replacement for a sticks graph when the backend doesn't support sticks directly.
Convert it into a line chart that traces the sticks, and a scatter that sets markers at the points.
"""
function sticksHack(; kw...)
dLine = Dict(kw)
dScatter = copy(dLine)
# these are the line vertices
x = Float64[]
y = Float64[]
fillto = dLine[:fillto] == nothing ? 0.0 : dLine[:fillto]
# calculate the vertices
yScatter = dScatter[:y]
for (i,xi) in enumerate(dScatter[:x])
yi = yScatter[i]
for j in 1:3 push!(x, xi) end
append!(y, [fillto, yScatter[i], fillto])
end
# change the line args
dLine[:x] = x
dLine[:y] = y
dLine[:linetype] = :line
dLine[:marker] = :none
dLine[:fillto] = nothing
# change the scatter args
dScatter[:linetype] = :none
dLine, dScatter
end
function regressionXY(x, y)
# regress
β, α = [x ones(length(x))] \ y
# make a line segment
regx = [minimum(x), maximum(x)]
regy = β * regx + α
regx, regy
end
# Some conversion functions
# note: I borrowed these conversion constants from Compose.jl's Measure
const INCH_SCALAR = 25.4
const PX_SCALAR = 1 / 3.78
inch2px(inches::Real) = float(inches * INCH_SCALAR / PX_SCALAR)
px2inch(px::Real) = float(px * PX_SCALAR / INCH_SCALAR)
inch2mm(inches::Real) = float(inches * INCH_SCALAR)
mm2inch(mm::Real) = float(mm / INCH_SCALAR)
px2mm(px::Real) = float(px * PX_SCALAR)
mm2px(mm::Real) = float(px / PX_SCALAR)