Merge pull request #2304 from michakraus/master

Generalized array fixes
This commit is contained in:
Daniel Schwabeneder 2019-12-07 11:04:13 +01:00 committed by GitHub
commit 3459bcd817
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 74 additions and 70 deletions

View File

@ -1098,7 +1098,7 @@ function extractGroupArgs(v::AVec, args...; legendEntry = string)
if n > 100 if n > 100
@warn("You created n=$n groups... Is that intended?") @warn("You created n=$n groups... Is that intended?")
end end
groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels] groupIds = Vector{Int}[filter(i -> v[i] == glab, eachindex(v)) for glab in groupLabels]
GroupBy(map(legendEntry, groupLabels), groupIds) GroupBy(map(legendEntry, groupLabels), groupIds)
end end
@ -1106,7 +1106,7 @@ legendEntryFromTuple(ns::Tuple) = join(ns, ' ')
# this is when given a tuple of vectors of values to group by # this is when given a tuple of vectors of values to group by
function extractGroupArgs(vs::Tuple, args...) function extractGroupArgs(vs::Tuple, args...)
isempty(vs) && return GroupBy([""], [1:size(args[1],1)]) isempty(vs) && return GroupBy([""], [axes(args[1],1)])
v = map(tuple, vs...) v = map(tuple, vs...)
extractGroupArgs(v, args...; legendEntry = legendEntryFromTuple) extractGroupArgs(v, args...; legendEntry = legendEntryFromTuple)
end end
@ -1116,7 +1116,7 @@ legendEntryFromTuple(ns::NamedTuple) =
join(["$k = $v" for (k, v) in pairs(ns)], ", ") join(["$k = $v" for (k, v) in pairs(ns)], ", ")
function extractGroupArgs(vs::NamedTuple, args...) function extractGroupArgs(vs::NamedTuple, args...)
isempty(vs) && return GroupBy([""], [1:size(args[1],1)]) isempty(vs) && return GroupBy([""], [axes(args[1],1)])
v = map(NamedTuple{keys(vs)}tuple, values(vs)...) v = map(NamedTuple{keys(vs)}tuple, values(vs)...)
extractGroupArgs(v, args...; legendEntry = legendEntryFromTuple) extractGroupArgs(v, args...; legendEntry = legendEntryFromTuple)
end end
@ -1225,7 +1225,8 @@ convertLegendValue(v::AbstractArray) = map(convertLegendValue, v)
# anything else is returned as-is # anything else is returned as-is
function slice_arg(v::AMat, idx::Int) function slice_arg(v::AMat, idx::Int)
c = mod1(idx, size(v,2)) c = mod1(idx, size(v,2))
size(v,1) == 1 ? v[1,c] : v[:,c] m,n = axes(v)
size(v,1) == 1 ? v[first(m),n[c]] : v[:,n[c]]
end end
slice_arg(wrapper::InputWrapper, idx) = wrapper.obj slice_arg(wrapper::InputWrapper, idx) = wrapper.obj
slice_arg(v, idx) = v slice_arg(v, idx) = v

View File

@ -577,10 +577,10 @@ end
# add the discrete value for each item. return the continuous values and the indices # add the discrete value for each item. return the continuous values and the indices
function discrete_value!(axis::Axis, v::AVec) function discrete_value!(axis::Axis, v::AVec)
n = length(v) n = eachindex(v)
cvec = zeros(n) cvec = zeros(axes(v))
discrete_indices = zeros(Int, n) discrete_indices = similar(Array{Int}, axes(v))
for i=1:n for i in n
cvec[i], discrete_indices[i] = discrete_value!(axis, v[i]) cvec[i], discrete_indices[i] = discrete_value!(axis, v[i])
end end
cvec, discrete_indices cvec, discrete_indices
@ -588,10 +588,10 @@ end
# add the discrete value for each item. return the continuous values and the indices # add the discrete value for each item. return the continuous values and the indices
function discrete_value!(axis::Axis, v::AMat) function discrete_value!(axis::Axis, v::AMat)
n,m = size(v) n,m = axes(v)
cmat = zeros(n,m) cmat = zeros(axes(v))
discrete_indices = zeros(Int, n, m) discrete_indices = similar(Array{Int}, axes(v))
for i=1:n, j=1:m for i in n, j in m
cmat[i,j], discrete_indices[i,j] = discrete_value!(axis, v[i,j]) cmat[i,j], discrete_indices[i,j] = discrete_value!(axis, v[i,j])
end end
cmat, discrete_indices cmat, discrete_indices

View File

@ -197,7 +197,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot)
if xaxis[:grid] if xaxis[:grid]
gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid])
gr_set_transparency(xaxis[:foreground_color_grid], xaxis[:gridalpha]) gr_set_transparency(xaxis[:foreground_color_grid], xaxis[:gridalpha])
for i in 1:length(α) for i in eachindex(α)
GR.polyline([sinf[i], 0], [cosf[i], 0]) GR.polyline([sinf[i], 0], [cosf[i], 0])
end end
end end
@ -206,7 +206,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot)
if yaxis[:grid] if yaxis[:grid]
gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid])
gr_set_transparency(yaxis[:foreground_color_grid], yaxis[:gridalpha]) gr_set_transparency(yaxis[:foreground_color_grid], yaxis[:gridalpha])
for i in 1:length(rtick_values) for i in eachindex(rtick_values)
r = (rtick_values[i] - rmin) / (rmax - rmin) r = (rtick_values[i] - rmin) / (rmax - rmin)
if r <= 1.0 && r >= 0.0 if r <= 1.0 && r >= 0.0
GR.drawarc(-r, r, -r, r, 0, 359) GR.drawarc(-r, r, -r, r, 0, 359)
@ -223,7 +223,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot)
#draw angular ticks #draw angular ticks
if xaxis[:showaxis] if xaxis[:showaxis]
GR.drawarc(-1, 1, -1, 1, 0, 359) GR.drawarc(-1, 1, -1, 1, 0, 359)
for i in 1:length(α) for i in eachindex(α)
x, y = GR.wctondc(1.1 * sinf[i], 1.1 * cosf[i]) x, y = GR.wctondc(1.1 * sinf[i], 1.1 * cosf[i])
GR.textext(x, y, string((360-α[i])%360, "^o")) GR.textext(x, y, string((360-α[i])%360, "^o"))
end end
@ -231,7 +231,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot)
#draw radial ticks #draw radial ticks
if yaxis[:showaxis] if yaxis[:showaxis]
for i in 1:length(rtick_values) for i in eachindex(rtick_values)
r = (rtick_values[i] - rmin) / (rmax - rmin) r = (rtick_values[i] - rmin) / (rmax - rmin)
if r <= 1.0 && r >= 0.0 if r <= 1.0 && r >= 0.0
x, y = GR.wctondc(0.05, r) x, y = GR.wctondc(0.05, r)
@ -305,7 +305,7 @@ function gr_draw_markers(series::Series, x, y, clims, msize = series[:markersize
shapes = series[:markershape] shapes = series[:markershape]
if shapes != :none if shapes != :none
for i=1:length(x) for i=eachindex(x)
msi = _cycle(msize, i) msi = _cycle(msize, i)
shape = _cycle(shapes, i) shape = _cycle(shapes, i)
cfunc = isa(shape, Shape) ? gr_set_fillcolor : gr_set_markercolor cfunc = isa(shape, Shape) ? gr_set_fillcolor : gr_set_markercolor

View File

@ -180,11 +180,11 @@ function pgf_series(sp::Subplot, series::Series)
end end
# PGFPlots can't handle non-Vector? # PGFPlots can't handle non-Vector?
args = map(a -> if typeof(a) <: AbstractVector && typeof(a) != Vector # args = map(a -> if typeof(a) <: AbstractVector && typeof(a) != Vector
collect(a) # collect(a)
else # else
a # a
end, args) # end, args)
if st in (:contour, :histogram2d) if st in (:contour, :histogram2d)
style = [] style = []

View File

@ -351,7 +351,7 @@ end
function plotly_colorscale(grad::ColorGradient, α) function plotly_colorscale(grad::ColorGradient, α)
[[grad.values[i], rgba_string(plot_color(grad.colors[i], α))] for i in 1:length(grad.colors)] [[grad.values[i], rgba_string(plot_color(grad.colors[i], α))] for i in eachindex(grad.colors)]
end end
plotly_colorscale(c::Colorant,α) = plotly_colorscale(_as_gradient(c),α) plotly_colorscale(c::Colorant,α) = plotly_colorscale(_as_gradient(c),α)
function plotly_colorscale(c::AbstractVector{<:RGBA}, α) function plotly_colorscale(c::AbstractVector{<:RGBA}, α)
@ -392,7 +392,7 @@ end
# we split by NaNs and then construct/destruct the shapes to get the closed coords # we split by NaNs and then construct/destruct the shapes to get the closed coords
function plotly_close_shapes(x, y) function plotly_close_shapes(x, y)
xs, ys = nansplit(x), nansplit(y) xs, ys = nansplit(x), nansplit(y)
for i=1:length(xs) for i=eachindex(xs)
shape = Shape(xs[i], ys[i]) shape = Shape(xs[i], ys[i])
xs[i], ys[i] = coords(shape) xs[i], ys[i] = coords(shape)
end end
@ -415,6 +415,7 @@ function plotly_data(series::Series, letter::Symbol, data)
end end
end end
plotly_data(v) = v !== nothing ? collect(v) : v plotly_data(v) = v !== nothing ? collect(v) : v
plotly_data(v::AbstractArray) = v
plotly_data(surf::Surface) = surf.surf plotly_data(surf::Surface) = surf.surf
plotly_data(v::AbstractArray{R}) where {R<:Rational} = float(v) plotly_data(v::AbstractArray{R}) where {R<:Rational} = float(v)

View File

@ -187,7 +187,7 @@ end
# end # end
function get_locator_and_formatter(vals::AVec) function get_locator_and_formatter(vals::AVec)
pyticker."FixedLocator"(1:length(vals)), pyticker."FixedFormatter"(vals) pyticker."FixedLocator"(eachindex(vals)), pyticker."FixedFormatter"(vals)
end end
function add_pyfixedformatter(cbar, vals::AVec) function add_pyfixedformatter(cbar, vals::AVec)
@ -535,7 +535,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
shapes = series[:markershape] shapes = series[:markershape]
msc = py_markerstrokecolor(series) msc = py_markerstrokecolor(series)
lw = py_thickness_scale(plt, series[:markerstrokewidth]) lw = py_thickness_scale(plt, series[:markerstrokewidth])
for i=1:length(y) for i=eachindex(y)
extrakw[:c] = _cycle(markercolor, i) extrakw[:c] = _cycle(markercolor, i)
push!(handle, ax."scatter"(_cycle(x,i), _cycle(y,i); push!(handle, ax."scatter"(_cycle(x,i), _cycle(y,i);
@ -564,7 +564,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series)
delete!(extrakw, :c) delete!(extrakw, :c)
for i=1:length(y) for i=eachindex(y)
cur_marker = py_marker(_cycle(shapes,i)) cur_marker = py_marker(_cycle(shapes,i))
if ( cur_marker == prev_marker ) if ( cur_marker == prev_marker )
@ -1013,7 +1013,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend})
kw = KW() kw = KW()
if !isempty(sp[:zaxis][:discrete_values]) && colorbar_series[:seriestype] == :heatmap if !isempty(sp[:zaxis][:discrete_values]) && colorbar_series[:seriestype] == :heatmap
locator, formatter = get_locator_and_formatter(sp[:zaxis][:discrete_values]) locator, formatter = get_locator_and_formatter(sp[:zaxis][:discrete_values])
# kw[:values] = 1:length(sp[:zaxis][:discrete_values]) # kw[:values] = eachindex(sp[:zaxis][:discrete_values])
kw[:values] = sp[:zaxis][:continuous_values] kw[:values] = sp[:zaxis][:continuous_values]
kw[:ticks] = locator kw[:ticks] = locator
kw[:format] = formatter kw[:format] = formatter

View File

@ -187,7 +187,7 @@ end
function scale!(shape::Shape, x::Real, y::Real = x, c = center(shape)) function scale!(shape::Shape, x::Real, y::Real = x, c = center(shape))
sx, sy = coords(shape) sx, sy = coords(shape)
cx, cy = c cx, cy = c
for i=1:length(sx) for i=eachindex(sx)
sx[i] = (sx[i] - cx) * x + cx sx[i] = (sx[i] - cx) * x + cx
sy[i] = (sy[i] - cy) * y + cy sy[i] = (sy[i] - cy) * y + cy
end end
@ -202,7 +202,7 @@ end
"translate a Shape in space" "translate a Shape in space"
function translate!(shape::Shape, x::Real, y::Real = x) function translate!(shape::Shape, x::Real, y::Real = x)
sx, sy = coords(shape) sx, sy = coords(shape)
for i=1:length(sx) for i=eachindex(sx)
sx[i] += x sx[i] += x
sy[i] += y sy[i] += y
end end
@ -230,7 +230,7 @@ end
function rotate!(shape::Shape, Θ::Real, c = center(shape)) function rotate!(shape::Shape, Θ::Real, c = center(shape))
x, y = coords(shape) x, y = coords(shape)
cx, cy = c cx, cy = c
for i=1:length(x) for i=eachindex(x)
xi = rotate_x(x[i], y[i], Θ, cx, cy) xi = rotate_x(x[i], y[i], Θ, cx, cy)
yi = rotate_y(x[i], y[i], Θ, cx, cy) yi = rotate_y(x[i], y[i], Θ, cx, cy)
x[i], y[i] = xi, yi x[i], y[i] = xi, yi

View File

@ -545,7 +545,7 @@ function test_examples(pkgname::Symbol; debug = false, disp = true, sleep = noth
skip = [], only = nothing) skip = [], only = nothing)
Plots._debugMode.on = debug Plots._debugMode.on = debug
plts = Dict() plts = Dict()
for i in 1:length(_examples) for i in eachindex(_examples)
only !== nothing && !(i in only) && continue only !== nothing && !(i in only) && continue
i in skip && continue i in skip && continue
try try

View File

@ -12,7 +12,7 @@ function _expand_seriestype_array(plotattributes::KW, args)
if typeof(sts) <: AbstractArray if typeof(sts) <: AbstractArray
delete!(plotattributes, :seriestype) delete!(plotattributes, :seriestype)
rd = Vector{RecipeData}(undef, size(sts, 1)) rd = Vector{RecipeData}(undef, size(sts, 1))
for r in 1:size(sts, 1) for r in axes(sts, 1)
dc = copy(plotattributes) dc = copy(plotattributes)
dc[:seriestype] = sts[r:r,:] dc[:seriestype] = sts[r:r,:]
rd[r] = RecipeData(dc, args) rd[r] = RecipeData(dc, args)

View File

@ -364,7 +364,7 @@ end
0.5 * _bar_width 0.5 * _bar_width
end end
else else
Float64[0.5_cycle(bw,i) for i=1:length(procx)] Float64[0.5_cycle(bw,i) for i=eachindex(procx)]
end end
# make fillto a vector... default fills to 0 # make fillto a vector... default fills to 0
@ -998,7 +998,7 @@ function get_xy(o::OHLC, x, xdiff)
end end
# get the joined vector # get the joined vector
function get_xy(v::AVec{OHLC}, x = 1:length(v)) function get_xy(v::AVec{OHLC}, x = eachindex(v))
xdiff = 0.3ignorenan_mean(abs.(diff(x))) xdiff = 0.3ignorenan_mean(abs.(diff(x)))
x_out, y_out = zeros(0), zeros(0) x_out, y_out = zeros(0), zeros(0)
for (i,ohlc) in enumerate(v) for (i,ohlc) in enumerate(v)
@ -1056,8 +1056,8 @@ end
@assert length(g.args) == 1 && typeof(g.args[1]) <: AbstractMatrix @assert length(g.args) == 1 && typeof(g.args[1]) <: AbstractMatrix
seriestype := :spy seriestype := :spy
mat = g.args[1] mat = g.args[1]
n,m = size(mat) n,m = axes(mat)
Plots.SliceIt, 1:m, 1:n, Surface(mat) Plots.SliceIt, m, n, Surface(mat)
end end
@recipe function f(::Type{Val{:spy}}, x,y,z) @recipe function f(::Type{Val{:spy}}, x,y,z)
@ -1185,7 +1185,7 @@ end
seriestype := :shape seriestype := :shape
# create a filled polygon for each item # create a filled polygon for each item
for c=1:size(weights,2) for c=axes(weights,2)
sx = vcat(weights[:,c], c==1 ? zeros(n) : reverse(weights[:,c-1])) sx = vcat(weights[:,c], c==1 ? zeros(n) : reverse(weights[:,c-1]))
sy = vcat(returns, reverse(returns)) sy = vcat(returns, reverse(returns))
@series Plots.isvertical(plotattributes) ? (sx, sy) : (sy, sx) @series Plots.isvertical(plotattributes) ? (sx, sy) : (sy, sx)
@ -1206,9 +1206,9 @@ julia> areaplot(1:3, [1 2 3; 7 8 9; 4 5 6], seriescolor = [:red :green :blue], f
@recipe function f(a::AreaPlot) @recipe function f(a::AreaPlot)
data = cumsum(a.args[end], dims=2) data = cumsum(a.args[end], dims=2)
x = length(a.args) == 1 ? (1:size(data, 1)) : a.args[1] x = length(a.args) == 1 ? (axes(data, 1)) : a.args[1]
seriestype := :line seriestype := :line
for i in 1:size(data, 2) for i in axes(data, 2)
@series begin @series begin
fillrange := i > 1 ? data[:,i-1] : 0 fillrange := i > 1 ? data[:,i-1] : 0
x, data[:,i] x, data[:,i]

View File

@ -47,7 +47,7 @@ function convertToAnyVector(v::AMat{<:DataPoint}, plotattributes)
if all3D(plotattributes) if all3D(plotattributes)
Any[prepareSeriesData(Surface(v))] Any[prepareSeriesData(Surface(v))]
else else
Any[prepareSeriesData(v[:, i]) for i in 1:size(v, 2)] Any[prepareSeriesData(v[:, i]) for i in axes(v, 2)]
end end
end end
@ -70,13 +70,13 @@ process_ribbon(ribbon::Tuple{Any,Any}, plotattributes) = collect(zip(convertToAn
# TODO: can we avoid the copy here? one error that crops up is that mapping functions over the same array # TODO: can we avoid the copy here? one error that crops up is that mapping functions over the same array
# result in that array being shared. push!, etc will add too many items to that array # result in that array being shared. push!, etc will add too many items to that array
compute_x(x::Nothing, y::Nothing, z) = 1:size(z,1) compute_x(x::Nothing, y::Nothing, z) = axes(z,1)
compute_x(x::Nothing, y, z) = 1:size(y,1) compute_x(x::Nothing, y, z) = axes(y,1)
compute_x(x::Function, y, z) = map(x, y) compute_x(x::Function, y, z) = map(x, y)
compute_x(x, y, z) = copy(x) compute_x(x, y, z) = copy(x)
# compute_y(x::Void, y::Function, z) = error() # compute_y(x::Void, y::Function, z) = error()
compute_y(x::Nothing, y::Nothing, z) = 1:size(z,2) compute_y(x::Nothing, y::Nothing, z) = axes(z,2)
compute_y(x, y::Function, z) = map(y, x) compute_y(x, y::Function, z) = map(y, x)
compute_y(x, y, z) = copy(y) compute_y(x, y, z) = copy(y)
@ -282,9 +282,9 @@ all3D(plotattributes::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :hea
# return a surface if this is a 3d plot, otherwise let it be sliced up # return a surface if this is a 3d plot, otherwise let it be sliced up
@recipe function f(mat::AMat{T}) where T<:Union{Integer,AbstractFloat,Missing} @recipe function f(mat::AMat{T}) where T<:Union{Integer,AbstractFloat,Missing}
if all3D(plotattributes) if all3D(plotattributes)
n,m = size(mat) n,m = axes(mat)
wrap_surfaces(plotattributes) wrap_surfaces(plotattributes)
SliceIt, 1:m, 1:n, Surface(mat) SliceIt, m, n, Surface(mat)
else else
SliceIt, nothing, mat, nothing SliceIt, nothing, mat, nothing
end end
@ -294,9 +294,9 @@ end
@recipe function f(fmt::Formatted{T}) where T<:AbstractMatrix @recipe function f(fmt::Formatted{T}) where T<:AbstractMatrix
if all3D(plotattributes) if all3D(plotattributes)
mat = fmt.data mat = fmt.data
n,m = size(mat) n,m = axes(mat)
wrap_surfaces(plotattributes) wrap_surfaces(plotattributes)
SliceIt, 1:m, 1:n, Formatted(Surface(mat), fmt.formatter) SliceIt, m, n, Formatted(Surface(mat), fmt.formatter)
else else
SliceIt, nothing, fmt, nothing SliceIt, nothing, fmt, nothing
end end
@ -319,35 +319,35 @@ function clamp_greys!(mat::AMat{T}) where T<:Gray
end end
@recipe function f(mat::AMat{T}) where T<:Gray @recipe function f(mat::AMat{T}) where T<:Gray
n, m = size(mat) n, m = axes(mat)
if is_seriestype_supported(:image) if is_seriestype_supported(:image)
seriestype := :image seriestype := :image
yflip --> true yflip --> true
SliceIt, 1:m, 1:n, Surface(clamp_greys!(mat)) SliceIt, m, n, Surface(clamp_greys!(mat))
else else
seriestype := :heatmap seriestype := :heatmap
yflip --> true yflip --> true
cbar --> false cbar --> false
fillcolor --> ColorGradient([:black, :white]) fillcolor --> ColorGradient([:black, :white])
SliceIt, 1:m, 1:n, Surface(clamp!(convert(Matrix{Float64}, mat), 0., 1.)) SliceIt, m, n, Surface(clamp!(convert(Matrix{Float64}, mat), 0., 1.))
end end
end end
# # images - colors # # images - colors
@recipe function f(mat::AMat{T}) where T<:Colorant @recipe function f(mat::AMat{T}) where T<:Colorant
n, m = size(mat) n, m = axes(mat)
if is_seriestype_supported(:image) if is_seriestype_supported(:image)
seriestype := :image seriestype := :image
yflip --> true yflip --> true
SliceIt, 1:m, 1:n, Surface(mat) SliceIt, m, n, Surface(mat)
else else
seriestype := :heatmap seriestype := :heatmap
yflip --> true yflip --> true
cbar --> false cbar --> false
z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat) z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat)
SliceIt, 1:m, 1:n, Surface(z) SliceIt, m, n, Surface(z)
end end
end end
@ -366,7 +366,7 @@ end
@recipe function f(shapes::AMat{Shape}) @recipe function f(shapes::AMat{Shape})
seriestype --> :shape seriestype --> :shape
for j in 1:size(shapes,2) for j in axes(shapes,2)
@series coords(vec(shapes[:,j])) @series coords(vec(shapes[:,j]))
end end
end end
@ -583,7 +583,7 @@ end
# end # end
splittable_kw(key, val, lengthGroup) = false splittable_kw(key, val, lengthGroup) = false
splittable_kw(key, val::AbstractArray, lengthGroup) = !(key in (:group, :color_palette)) && size(val,1) == lengthGroup splittable_kw(key, val::AbstractArray, lengthGroup) = !(key in (:group, :color_palette)) && length(axes(val,1)) == lengthGroup
splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengthGroup)) splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengthGroup))
splittable_kw(key, val::SeriesAnnotations, lengthGroup) = splittable_kw(key, val.strs, lengthGroup) splittable_kw(key, val::SeriesAnnotations, lengthGroup) = splittable_kw(key, val.strs, lengthGroup)
@ -597,7 +597,7 @@ end
function groupedvec2mat(x_ind, x, y::AbstractArray, groupby, def_val = y[1]) function groupedvec2mat(x_ind, x, y::AbstractArray, groupby, def_val = y[1])
y_mat = Array{promote_type(eltype(y), typeof(def_val))}(undef, length(keys(x_ind)), length(groupby.groupLabels)) y_mat = Array{promote_type(eltype(y), typeof(def_val))}(undef, length(keys(x_ind)), length(groupby.groupLabels))
fill!(y_mat, def_val) fill!(y_mat, def_val)
for i in 1:length(groupby.groupLabels) for i in eachindex(groupby.groupLabels)
xi = x[groupby.groupIds[i]] xi = x[groupby.groupIds[i]]
yi = y[groupby.groupIds[i]] yi = y[groupby.groupIds[i]]
y_mat[getindex.(Ref(x_ind), xi), i] = yi y_mat[getindex.(Ref(x_ind), xi), i] = yi
@ -630,7 +630,7 @@ group_as_matrix(t) = false
if length(g.args) == 1 if length(g.args) == 1
x = zeros(Int, lengthGroup) x = zeros(Int, lengthGroup)
for indexes in groupby.groupIds for indexes in groupby.groupIds
x[indexes] = 1:length(indexes) x[indexes] = eachindex(indexes)
end end
last_args = g.args last_args = g.args
else else
@ -638,7 +638,7 @@ group_as_matrix(t) = false
last_args = g.args[2:end] last_args = g.args[2:end]
end end
x_u = unique(sort(x)) x_u = unique(sort(x))
x_ind = Dict(zip(x_u, 1:length(x_u))) x_ind = Dict(zip(x_u, eachindex(x_u)))
for (key,val) in plotattributes for (key,val) in plotattributes
if splittable_kw(key, val, lengthGroup) if splittable_kw(key, val, lengthGroup)
:($key) := groupedvec2mat(x_ind, x, val, groupby) :($key) := groupedvec2mat(x_ind, x, val, groupby)

View File

@ -43,7 +43,7 @@ function barHack(; kw...)
# estimate the edges # estimate the edges
dists = diff(midpoints) * 0.5 dists = diff(midpoints) * 0.5
edges = zeros(length(midpoints)+1) edges = zeros(length(midpoints)+1)
for i in 1:length(edges) for i in eachindex(edges)
if i == 1 if i == 1
edge = midpoints[1] - dists[1] edge = midpoints[1] - dists[1]
elseif i == length(edges) elseif i == length(edges)
@ -56,7 +56,7 @@ function barHack(; kw...)
x = Float64[] x = Float64[]
y = Float64[] y = Float64[]
for i in 1:length(heights) for i in eachindex(heights)
e1, e2 = edges[i:i+1] e1, e2 = edges[i:i+1]
append!(x, [e1, e1, e2, e2]) append!(x, [e1, e1, e2, e2])
append!(y, [fillrange, heights[i], heights[i], fillrange]) append!(y, [fillrange, heights[i], heights[i], fillrange])
@ -182,13 +182,15 @@ end
mutable struct SegmentsIterator mutable struct SegmentsIterator
args::Tuple args::Tuple
n::Int n1::Int
n2::Int
end end
function iter_segments(args...) function iter_segments(args...)
tup = Plots.wraptuple(args) tup = Plots.wraptuple(args)
n = maximum(map(length, tup)) n1 = minimum(map(firstindex, tup))
SegmentsIterator(tup, n) n2 = maximum(map(lastindex, tup))
SegmentsIterator(tup, n1, n2)
end end
function iter_segments(series::Series) function iter_segments(series::Series)
@ -197,9 +199,9 @@ function iter_segments(series::Series)
return UnitRange{Int}[] return UnitRange{Int}[]
elseif has_attribute_segments(series) elseif has_attribute_segments(series)
if series[:seriestype] in (:scatter, :scatter3d) if series[:seriestype] in (:scatter, :scatter3d)
return [[i] for i in 1:length(y)] return [[i] for i in eachindex(y)]
else else
return [i:(i + 1) for i in 1:(length(y) - 1)] return [i:(i + 1) for i in firstindex(y):lastindex(y)-1]
end end
else else
segs = UnitRange{Int}[] segs = UnitRange{Int}[]
@ -217,13 +219,13 @@ anynan(args::Tuple) = i -> anynan(i,args)
anynan(istart::Int, iend::Int, args::Tuple) = any(anynan(args), istart:iend) anynan(istart::Int, iend::Int, args::Tuple) = any(anynan(args), istart:iend)
allnan(istart::Int, iend::Int, args::Tuple) = all(anynan(args), istart:iend) allnan(istart::Int, iend::Int, args::Tuple) = all(anynan(args), istart:iend)
function Base.iterate(itr::SegmentsIterator, nextidx::Int = 1) function Base.iterate(itr::SegmentsIterator, nextidx::Int = itr.n1)
i = findfirst(!anynan(itr.args), nextidx:itr.n) i = findfirst(!anynan(itr.args), nextidx:itr.n2)
i === nothing && return nothing i === nothing && return nothing
nextval = nextidx + i - 1 nextval = nextidx + i - 1
j = findfirst(anynan(itr.args), nextval:itr.n) j = findfirst(anynan(itr.args), nextval:itr.n2)
nextnan = j === nothing ? itr.n + 1 : nextval + j - 1 nextnan = j === nothing ? itr.n2 + 1 : nextval + j - 1
nextval:nextnan-1, nextnan nextval:nextnan-1, nextnan
end end