Improve data preprocessing for bar and histogram plots
Fixes broken bar-plots with non-numeric a-axes
This commit is contained in:
parent
a523903c15
commit
67b4157e25
@ -323,7 +323,7 @@ end
|
||||
|
||||
# create a bar plot as a filled step function
|
||||
@recipe function f(::Type{Val{:bar}}, x, y, z)
|
||||
procx, procy, xscale, yscale, baseline = _preprocess_binlike(d, x, y)
|
||||
procx, procy, xscale, yscale, baseline, wautolims = _preprocess_barlike(d, x, y)
|
||||
nx, ny = length(procx), length(procy)
|
||||
axis = d[:subplot][isvertical(d) ? :xaxis : :yaxis]
|
||||
cv = [discrete_value!(axis, xi)[1] for xi=procx]
|
||||
@ -380,6 +380,7 @@ end
|
||||
x := xseg.pts
|
||||
y := yseg.pts
|
||||
seriestype := :shape
|
||||
ylims --> wautolims
|
||||
()
|
||||
end
|
||||
@deps bar shape
|
||||
@ -402,39 +403,64 @@ function _scale_adjusted_values{T<:AbstractFloat}(::Type{T}, V::AbstractVector,
|
||||
end
|
||||
end
|
||||
|
||||
function _hist_ylim_lo{T<:Real}(ymin::T, yscale::Symbol)
|
||||
if (yscale in _logScales)
|
||||
ymin / T(_logScaleBases[yscale]^log10(2))
|
||||
|
||||
function _binbarlike_baseline{T<:Real}(min_value::T, scale::Symbol)
|
||||
if (scale in _logScales)
|
||||
!isnan(min_value) ? min_value / T(_logScaleBases[scale]^log10(2)) : T(1E-3)
|
||||
else
|
||||
zero(T)
|
||||
end
|
||||
end
|
||||
|
||||
function _hist_ylim_hi{T<:Real}(ymax::T, yscale::Symbol)
|
||||
if (yscale in _logScales)
|
||||
ymax * T(_logScaleBases[yscale]^log10(2))
|
||||
function _binbarlike_autolims{T<:Real}(min_value::T, max_value::T, scale::Symbol)
|
||||
lo = if (scale in _logScales)
|
||||
_binbarlike_baseline(min_value, scale)
|
||||
else
|
||||
ymax * T(1.1)
|
||||
end
|
||||
min(min_value * T(1.1), zero(T))
|
||||
end::T
|
||||
|
||||
hi = if !isnan(max_value)
|
||||
if (scale in _logScales)
|
||||
max_value * T(_logScaleBases[scale]^log10(2))
|
||||
else
|
||||
max(max_value * T(1.1), zero(T))
|
||||
end
|
||||
else
|
||||
one(T)
|
||||
end::T
|
||||
|
||||
(lo, hi)
|
||||
end
|
||||
|
||||
|
||||
function _preprocess_binbarlike_weights{T<:AbstractFloat}(::Type{T}, w, wscale::Symbol)
|
||||
w_adj = _scale_adjusted_values(T, w, wscale)
|
||||
w_min = minimum(w_adj)
|
||||
w_max = maximum(w_adj)
|
||||
baseline = _binbarlike_baseline(w_min, wscale)
|
||||
autolims = _binbarlike_autolims(w_min, w_max,wscale)
|
||||
w_adj, baseline, autolims
|
||||
end
|
||||
|
||||
function _preprocess_barlike(d, x, y)
|
||||
xscale = get(d, :xscale, :identity)
|
||||
yscale = get(d, :yscale, :identity)
|
||||
weights, baseline, wautolims = _preprocess_binbarlike_weights(float(eltype(y)), y, yscale)
|
||||
x, weights, xscale, yscale, baseline, wautolims
|
||||
end
|
||||
|
||||
function _preprocess_binlike(d, x, y)
|
||||
xscale = get(d, :xscale, :identity)
|
||||
yscale = get(d, :yscale, :identity)
|
||||
|
||||
T = float(promote_type(eltype(x), eltype(y)))
|
||||
edge = map(T, x)
|
||||
weights = _scale_adjusted_values(T, y, yscale)
|
||||
w_min = minimum(weights)
|
||||
baseline = _hist_ylim_lo(isnan(w_min) ? one(T) : w_min, yscale)
|
||||
edge, weights, xscale, yscale, baseline
|
||||
edge = T.(x)
|
||||
weights, baseline, wautolims = _preprocess_binbarlike_weights(T, y, yscale)
|
||||
edge, weights, xscale, yscale, baseline, wautolims
|
||||
end
|
||||
|
||||
|
||||
|
||||
@recipe function f(::Type{Val{:barbins}}, x, y, z)
|
||||
edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y)
|
||||
edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, x, y)
|
||||
if (d[:bar_width] == nothing)
|
||||
bar_width := diff(edge)
|
||||
end
|
||||
@ -447,7 +473,7 @@ end
|
||||
|
||||
|
||||
@recipe function f(::Type{Val{:scatterbins}}, x, y, z)
|
||||
edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y)
|
||||
edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, x, y)
|
||||
xerror := diff(edge)/2
|
||||
x := _bin_centers(edge)
|
||||
y := weights
|
||||
@ -512,7 +538,7 @@ end
|
||||
@recipe function f(::Type{Val{:stepbins}}, x, y, z)
|
||||
axis = d[:subplot][Plots.isvertical(d) ? :xaxis : :yaxis]
|
||||
|
||||
edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y)
|
||||
edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, x, y)
|
||||
|
||||
xpts, ypts = _stepbins_path(edge, weights, baseline, xscale, yscale)
|
||||
if !isvertical(d)
|
||||
@ -539,7 +565,7 @@ end
|
||||
y := ypts
|
||||
seriestype := :path
|
||||
|
||||
ylims --> [baseline, _hist_ylim_hi(maximum(weights), yscale)]
|
||||
ylims --> wautolims
|
||||
()
|
||||
end
|
||||
Plots.@deps stepbins path
|
||||
@ -639,7 +665,7 @@ end
|
||||
|
||||
if d[:seriestype] == :scatterbins
|
||||
# Workaround, error bars currently not set correctly by scatterbins
|
||||
edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, h.edges[1], h.weights)
|
||||
edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, h.edges[1], h.weights)
|
||||
xerror --> diff(h.edges[1])/2
|
||||
seriestype := :scatter
|
||||
(Plots._bin_centers(edge), weights)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user