Change NaNMath implementation

We needed some functions to forward to Base methods, e.g. when non-`AbstractArray{<:AbstractFloat}` was passed
This commit is contained in:
Michael K. Borregaard 2017-06-01 22:19:38 +02:00
parent d29df4289e
commit 80d0d6ecc8
12 changed files with 59 additions and 48 deletions

View File

@ -10,7 +10,6 @@ using Base.Meta
@reexport using PlotThemes
import Showoff
import StatsBase
import NaNMath # define functions that ignores NaNs. To overcome the destructive effects of https://github.com/JuliaLang/julia/pull/12563
export
grid,
@ -107,6 +106,18 @@ export
# ---------------------------------------------------------
import NaNMath # define functions that ignores NaNs. To overcome the destructive effects of https://github.com/JuliaLang/julia/pull/12563
ignoreNaN_minimum{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.minimum(x)
ignoreNaN_minimum(x) = Base.minimum(x)
ignoreNaN_maximum{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.maximum(x)
ignoreNaN_maximum(x) = Base.maximum(x)
ignoreNaN_mean{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.mean(x)
ignoreNaN_mean(x) = Base.mean(x)
ignoreNaN_extrema{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.extrema(x)
ignoreNaN_extrema(x) = Base.extrema(x)
# ---------------------------------------------------------
import Measures
import Measures: Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h
const BBox = Measures.Absolute2DBox

View File

@ -118,7 +118,7 @@ Base.show(io::IO, axis::Axis) = dumpdict(axis.d, "Axis", true)
# Base.getindex(axis::Axis, k::Symbol) = getindex(axis.d, k)
Base.setindex!(axis::Axis, v, ks::Symbol...) = setindex!(axis.d, v, ks...)
Base.haskey(axis::Axis, k::Symbol) = haskey(axis.d, k)
NaNMath.extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax))
ignoreNaN_extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax))
const _scale_funcs = Dict{Symbol,Function}(
@ -349,11 +349,11 @@ function expand_extrema!(sp::Subplot, d::KW)
bw = d[:bar_width]
if bw == nothing
bw = d[:bar_width] = NaNMath.mean(diff(data))
bw = d[:bar_width] = ignoreNaN_mean(diff(data))
end
axis = sp.attr[Symbol(dsym, :axis)]
expand_extrema!(axis, NaNMath.maximum(data) + 0.5maximum(bw))
expand_extrema!(axis, NaNMath.minimum(data) - 0.5minimum(bw))
expand_extrema!(axis, ignoreNaN_maximum(data) + 0.5maximum(bw))
expand_extrema!(axis, ignoreNaN_minimum(data) - 0.5minimum(bw))
end
end

View File

@ -304,7 +304,7 @@ function extract_any_color(d, kw_args)
kw_args[:color_norm] = Vec2f0(clims)
end
elseif clims == :auto
kw_args[:color_norm] = Vec2f0(NaNMath.extrema(d[:y]))
kw_args[:color_norm] = Vec2f0(ignoreNaN_extrema(d[:y]))
end
end
else
@ -315,7 +315,7 @@ function extract_any_color(d, kw_args)
kw_args[:color_norm] = Vec2f0(clims)
end
elseif clims == :auto
kw_args[:color_norm] = Vec2f0(NaNMath.extrema(d[:y]))
kw_args[:color_norm] = Vec2f0(ignoreNaN_extrema(d[:y]))
else
error("Unsupported limits: $clims")
end
@ -482,7 +482,7 @@ function hover(to_hover, to_display, window)
end
function extract_extrema(d, kw_args)
xmin, xmax = NaNMath.extrema(d[:x]); ymin, ymax = NaNMath.extrema(d[:y])
xmin, xmax = ignoreNaN_extrema(d[:x]); ymin, ymax = ignoreNaN_extrema(d[:y])
kw_args[:primitive] = GeometryTypes.SimpleRectangle{Float32}(xmin, ymin, xmax-xmin, ymax-ymin)
nothing
end
@ -509,7 +509,7 @@ function extract_colornorm(d, kw_args)
else
d[:y]
end
kw_args[:color_norm] = Vec2f0(NaNMath.extrema(z))
kw_args[:color_norm] = Vec2f0(ignoreNaN_extrema(z))
kw_args[:intensity] = map(Float32, collect(z))
end
end
@ -781,7 +781,7 @@ function gl_bar(d, kw_args)
# compute half-width of bars
bw = nothing
hw = if bw == nothing
NaNMath.mean(diff(x))
ignoreNaN_mean(diff(x))
else
Float64[cycle(bw,i)*0.5 for i=1:length(x)]
end
@ -864,7 +864,7 @@ function gl_boxplot(d, kw_args)
end
# change q1 and q5 to show outliers
# using maximum and minimum values inside the limits
q1, q5 = NaNMath.extrema(inside)
q1, q5 = ignoreNaN_extrema(inside)
end
# Box
if notch
@ -1318,7 +1318,7 @@ function gl_contour(x, y, z, kw_args)
T = eltype(z)
levels = Contour.contours(map(T, x), map(T, y), z, h)
result = Point2f0[]
zmin, zmax = get(kw_args, :limits, Vec2f0(NaNMath.extrema(z)))
zmin, zmax = get(kw_args, :limits, Vec2f0(ignoreNaN_extrema(z)))
cmap = get(kw_args, :color_map, get(kw_args, :color, RGBA{Float32}(0,0,0,1)))
colors = RGBA{Float32}[]
for c in levels.contours
@ -1339,7 +1339,7 @@ end
function gl_heatmap(x,y,z, kw_args)
get!(kw_args, :color_norm, Vec2f0(NaNMath.extrema(z)))
get!(kw_args, :color_norm, Vec2f0(ignoreNaN_extrema(z)))
get!(kw_args, :color_map, Plots.make_gradient(cgrad()))
delete!(kw_args, :intensity)
I = GLVisualize.Intensity{1, Float32}

View File

@ -264,7 +264,7 @@ end
normalize_zvals(zv::Void) = zv
function normalize_zvals(zv::AVec)
vmin, vmax = NaNMath.extrema(zv)
vmin, vmax = ignoreNaN_extrema(zv)
if vmin == vmax
zeros(length(zv))
else
@ -639,7 +639,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
elseif ispolar(sp)
r = gr_set_viewport_polar()
rmin, rmax = GR.adjustrange(NaNMath.minimum(r), NaNMath.maximum(r))
rmin, rmax = GR.adjustrange(ignoreNaN_minimum(r), ignoreNaN_maximum(r))
# rmin, rmax = axis_limits(sp[:yaxis])
gr_polaraxes(rmin, rmax)
@ -824,7 +824,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
# create the colorbar of contour levels
if sp[:colorbar] != :none
gr_set_viewport_cmap(sp)
l = round(Int32, 1000 + (h - NaNMath.minimum(h)) / (NaNMath.maximum(h) - NaNMath.minimum(h)) * 255)
l = round(Int32, 1000 + (h - ignoreNaN_minimum(h)) / (ignoreNaN_maximum(h) - ignoreNaN_minimum(h)) * 255)
GR.setwindow(xmin, xmax, zmin, zmax)
GR.cellarray(xmin, xmax, zmax, zmin, 1, length(l), l)
ztick = 0.5 * GR.tick(zmin, zmax)

View File

@ -546,7 +546,7 @@ function plotly_series(plt::Plot, series::Series)
else
# grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha])
grad = as_gradient(series[:markercolor], series[:markeralpha])
zmin, zmax = NaNMath.extrema(series[:marker_z])
zmin, zmax = ignoreNaN_extrema(series[:marker_z])
zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line)
[rgba_string(grad[(zi - zmin) / zrange]) for zi in series[:marker_z]]
end

View File

@ -705,11 +705,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
# contours on the axis planes
if series[:contours]
for (zdir,mat) in (("x",x), ("y",y), ("z",z))
offset = (zdir == "y" ? NaNMath.maximum : NaNMath.minimum)(mat)
offset = (zdir == "y" ? ignoreNaN_maximum : ignoreNaN_minimum)(mat)
handle = ax[:contourf](x, y, z, levelargs...;
zdir = zdir,
cmap = py_fillcolormap(series),
offset = (zdir == "y" ? NaNMath.maximum : NaNMath.minimum)(mat) # where to draw the contour plane
offset = (zdir == "y" ? ignoreNaN_maximum : ignoreNaN_minimum)(mat) # where to draw the contour plane
)
push!(handles, handle)
needs_colorbar = true
@ -778,7 +778,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
end
clims = sp[:clims]
zmin, zmax = NaNMath.extrema(z)
zmin, zmax = ignoreNaN_extrema(z)
extrakw[:vmin] = (is_2tuple(clims) && isfinite(clims[1])) ? clims[1] : zmin
extrakw[:vmax] = (is_2tuple(clims) && isfinite(clims[2])) ? clims[2] : zmax
@ -926,7 +926,7 @@ function py_compute_axis_minval(axis::Axis)
for series in series_list(sp)
v = series.d[axis[:letter]]
if !isempty(v)
minval = NaNMath.min(minval, NaNMath.minimum(abs(v)))
minval = NaNMath.min(minval, ignoreNaN_minimum(abs(v)))
end
end
end

View File

@ -501,7 +501,7 @@ immutable ZValues
zrange::Tuple{Float64,Float64}
end
function zvalues{T<:Real}(values::AVec{T}, zrange::Tuple{T,T} = (NaNMath.minimum(values), NaNMath.maximum(values)))
function zvalues{T<:Real}(values::AVec{T}, zrange::Tuple{T,T} = (ignoreNaN_minimum(values), ignoreNaN_maximum(values)))
ZValues(collect(float(values)), map(Float64, zrange))
end
@ -659,7 +659,7 @@ function directed_curve(args...; kw...)
end
function extrema_plus_buffer(v, buffmult = 0.2)
vmin,vmax = NaNMath.extrema(v)
vmin,vmax = ignoreNaN_extrema(v)
vdiff = vmax-vmin
buffer = vdiff * buffmult
vmin - buffer, vmax + buffer

View File

@ -704,7 +704,7 @@ function link_axes!(axes::Axis...)
a1 = axes[1]
for i=2:length(axes)
a2 = axes[i]
expand_extrema!(a1, NaNMath.extrema(a2))
expand_extrema!(a1, ignoreNaN_extrema(a2))
for k in (:extrema, :discrete_values, :continuous_values, :discrete_map)
a2[k] = a1[k]
end

View File

@ -153,7 +153,7 @@ function _add_smooth_kw(kw_list::Vector{KW}, kw::KW)
if get(kw, :smooth, false)
x, y = kw[:x], kw[:y]
β, α = convert(Matrix{Float64}, [x ones(length(x))]) \ convert(Vector{Float64}, y)
sx = [NaNMath.minimum(x), NaNMath.maximum(x)]
sx = [ignoreNaN_minimum(x), ignoreNaN_maximum(x)]
sy = β * sx + α
push!(kw_list, merge(copy(kw), KW(
:seriestype => :path,

View File

@ -225,7 +225,7 @@ end
fr = if yaxis[:scale] == :identity
0.0
else
NaNMath.min(axis_limits(yaxis)[1], NaNMath.minimum(y))
NaNMath.min(axis_limits(yaxis)[1], ignoreNaN_minimum(y))
end
end
newx, newy = zeros(3n), zeros(3n)
@ -338,7 +338,7 @@ end
# compute half-width of bars
bw = d[:bar_width]
hw = if bw == nothing
0.5NaNMath.mean(diff(procx))
0.5ignoreNaN_mean(diff(procx))
else
Float64[0.5cycle(bw,i) for i=1:length(procx)]
end
@ -366,7 +366,7 @@ end
end
# widen limits out a bit
expand_extrema!(axis, widen(NaNMath.extrema(xseg.pts)...))
expand_extrema!(axis, widen(ignoreNaN_extrema(xseg.pts)...))
# switch back
if !isvertical(d)
@ -414,8 +414,8 @@ end
function _preprocess_binbarlike_weights{T<:AbstractFloat}(::Type{T}, w, wscale::Symbol)
w_adj = _scale_adjusted_values(T, w, wscale)
w_min = NaNMath.minimum(w_adj)
w_max = NaNMath.maximum(w_adj)
w_min = ignoreNaN_minimum(w_adj)
w_max = ignoreNaN_maximum(w_adj)
baseline = _binbarlike_baseline(w_min, wscale)
w_adj, baseline
end
@ -550,7 +550,7 @@ Plots.@deps stepbins path
function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto)
_cl(x) = ceil(Int, NaNMath.max(x, one(x)))
_iqr(v) = quantile(v, 0.75) - quantile(v, 0.25)
_span(v) = NaNMath.maximum(v) - NaNMath.minimum(v)
_span(v) = ignoreNaN_maximum(v) - ignoreNaN_minimum(v)
n_samples = length(linearindices(first(vs)))
# Estimator for number of samples in one row/column of bins along each axis:
@ -919,7 +919,7 @@ end
# get the joined vector
function get_xy(v::AVec{OHLC}, x = 1:length(v))
xdiff = 0.3NaNMath.mean(abs(diff(x)))
xdiff = 0.3ignoreNaN_mean(abs(diff(x)))
x_out, y_out = zeros(0), zeros(0)
for (i,ohlc) in enumerate(v)
ox,oy = get_xy(ohlc, x[i], xdiff)
@ -984,8 +984,8 @@ end
yflip := true
aspect_ratio := 1
rs, cs, zs = findnz(z.surf)
xlim := NaNMath.extrema(cs)
ylim := NaNMath.extrema(rs)
xlim := ignoreNaN_extrema(cs)
ylim := ignoreNaN_extrema(rs)
if d[:markershape] == :none
markershape := :circle
end
@ -1006,7 +1006,7 @@ end
"Adds a+bx... straight line over the current plot"
function abline!(plt::Plot, a, b; kw...)
plot!(plt, [NaNMath.extrema(plt)...], x -> b + a*x; kw...)
plot!(plt, [ignoreNaN_extrema(plt)...], x -> b + a*x; kw...)
end
abline!(args...; kw...) = abline!(current(), args...; kw...)

View File

@ -3,7 +3,7 @@ calcMidpoints(edges::AbstractVector) = Float64[0.5 * (edges[i] + edges[i+1]) for
"Make histogram-like bins of data"
function binData(data, nbins)
lo, hi = NaNMath.extrema(data)
lo, hi = ignoreNaN_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]
@ -109,7 +109,7 @@ function regressionXY(x, y)
β, α = convert(Matrix{Float64}, [x ones(length(x))]) \ convert(Vector{Float64}, y)
# make a line segment
regx = [NaNMath.minimum(x), NaNMath.maximum(x)]
regx = [ignoreNaN_minimum(x), ignoreNaN_maximum(x)]
regy = β * regx + α
regx, regy
end
@ -283,7 +283,7 @@ unzip{T}(xyuv::FixedSizeArrays.Vec{4,T}) = T[xyuv[1]], T[xyuv[2]], T[xyuv[
# given 2-element lims and a vector of data x, widen lims to account for the extrema of x
function _expand_limits(lims, x)
try
e1, e2 = NaNMath.extrema(x)
e1, e2 = ignoreNaN_extrema(x)
lims[1] = NaNMath.min(lims[1], e1)
lims[2] = NaNMath.max(lims[2], e2)
# catch err
@ -334,17 +334,17 @@ sortedkeys(d::Dict) = sort(collect(keys(d)))
"create an (n+1) list of the outsides of heatmap rectangles"
function heatmap_edges(v::AVec)
vmin, vmax = NaNMath.extrema(v)
vmin, vmax = ignoreNaN_extrema(v)
extra = 0.5 * (vmax-vmin) / (length(v)-1)
vcat(vmin-extra, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra)
end
function calc_r_extrema(x, y)
xmin, xmax = NaNMath.extrema(x)
ymin, ymax = NaNMath.extrema(y)
xmin, xmax = ignoreNaN_extrema(x)
ymin, ymax = ignoreNaN_extrema(y)
r = 0.5 * NaNMath.min(xmax - xmin, ymax - ymin)
NaNMath.extrema(r)
ignoreNaN_extrema(r)
end
function convert_to_polar(x, y, r_extrema = calc_r_extrema(x, y))
@ -645,7 +645,7 @@ end
# used in updating an existing series
extendSeriesByOne(v::UnitRange{Int}, n::Int = 1) = isempty(v) ? (1:n) : (minimum(v):maximum(v)+n)
extendSeriesByOne(v::AVec, n::Integer = 1) = isempty(v) ? (1:n) : vcat(v, (1:n) + NaNMath.maximum(v))
extendSeriesByOne(v::AVec, n::Integer = 1) = isempty(v) ? (1:n) : vcat(v, (1:n) + ignoreNaN_maximum(v))
extendSeriesData{T}(v::Range{T}, z::Real) = extendSeriesData(float(collect(v)), z)
extendSeriesData{T}(v::Range{T}, z::AVec) = extendSeriesData(float(collect(v)), z)
extendSeriesData{T}(v::AVec{T}, z::Real) = (push!(v, convert(T, z)); v)
@ -871,9 +871,9 @@ mm2px(mm::Real) = float(px / MM_PER_PX)
"Smallest x in plot"
xmin(plt::Plot) = NaNMath.minimum([NaNMath.minimum(series.d[:x]) for series in plt.series_list])
xmin(plt::Plot) = ignoreNaN_minimum([ignoreNaN_minimum(series.d[:x]) for series in plt.series_list])
"Largest x in plot"
xmax(plt::Plot) = NaNMath.maximum([NaNMath.maximum(series.d[:x]) for series in plt.series_list])
xmax(plt::Plot) = ignoreNaN_maximum([ignoreNaN_maximum(series.d[:x]) for series in plt.series_list])
"Extrema of x-values in plot"
NaNMath.extrema(plt::Plot) = (xmin(plt), xmax(plt))
ignoreNaN_extrema(plt::Plot) = (xmin(plt), xmax(plt))

View File

@ -78,12 +78,12 @@ facts("Axes") do
@fact typeof(axis) --> Plots.Axis
@fact Plots.discrete_value!(axis, "HI") --> (0.5, 1)
@fact Plots.discrete_value!(axis, :yo) --> (1.5, 2)
@fact Plots.NaNMath.extrema(axis) --> (0.5,1.5)
@fact Plots.ignoreNaN_extrema(axis) --> (0.5,1.5)
@fact axis[:discrete_map] --> Dict{Any,Any}(:yo => 2, "HI" => 1)
Plots.discrete_value!(axis, ["x$i" for i=1:5])
Plots.discrete_value!(axis, ["x$i" for i=0:2])
@fact Plots.NaNMath.extrema(axis) --> (0.5, 7.5)
@fact Plots.ignoreNaN_extrema(axis) --> (0.5, 7.5)
end