diff --git a/src/series.jl b/src/series.jl index b3aaedcd..2c8684af 100644 --- a/src/series.jl +++ b/src/series.jl @@ -553,33 +553,14 @@ end # # Lists of tuples and GeometryTypes.Points # # -------------------------------------------------------------------- # -# # if we get an unhandled tuple, just splat it in -@recipe f(tup::Tuple) = tup -# -# # (x,y) tuples -@recipe f(xy::AVec{Tuple{R1,R2}}) where {R1<:Number,R2<:Number} = unzip(xy) -@recipe f(xy::Tuple{R1,R2}) where {R1<:Number,R2<:Number} = [xy[1]], [xy[2]] +@recipe f(v::AVec{<:Tuple}) = unzip(v) +@recipe f(v::AVec{<:GeometryTypes.Point}) = unzip(v) +@recipe f(tup::Tuple) = [tup] +@recipe f(p::GeometryTypes.Point) = [p] -# -# # (x,y,z) tuples -@recipe f(xyz::AVec{Tuple{R1,R2,R3}}) where {R1<:Number,R2<:Number,R3<:Number} = unzip(xyz) -@recipe f(xyz::Tuple{R1,R2,R3}) where {R1<:Number,R2<:Number,R3<:Number} = [xyz[1]], [xyz[2]], [xyz[3]] - -# these might be points+velocity, or OHLC or something else -@recipe f(xyuv::AVec{Tuple{R1,R2,R3,R4}}) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv) -@recipe f(xyuv::Tuple{R1,R2,R3,R4}) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = [xyuv[1]], [xyuv[2]], [xyuv[3]], [xyuv[4]] - - -# -# # 2D Points -@recipe f(xy::AVec{GeometryTypes.Point{2,T}}) where {T<:Number} = unzip(xy) -@recipe f(xy::GeometryTypes.Point{2,T}) where {T<:Number} = [xy[1]], [xy[2]] - -# -# # 3D Points -@recipe f(xyz::AVec{GeometryTypes.Point{3,T}}) where {T<:Number} = unzip(xyz) -@recipe f(xyz::GeometryTypes.Point{3,T}) where {T<:Number} = [xyz[1]], [xyz[2]], [xyz[3]] +# Special case for 4-tuples in :ohlc series +@recipe f(xyuv::AVec{<:Tuple{R1,R2,R3,R4}}) where {R1,R2,R3,R4} = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv) # # # -------------------------------------------------------------------- diff --git a/src/utils.jl b/src/utils.jl index f86c7768..ea0ccc99 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -271,18 +271,17 @@ maketuple(x::Tuple{T,S}) where {T,S} = x mapFuncOrFuncs(f::Function, u::AVec) = map(f, u) mapFuncOrFuncs(fs::AVec{F}, u::AVec) where {F<:Function} = [map(f, u) for f in fs] -unzip(xy::AVec{Tuple{X,Y}}) where {X,Y} = [t[1] for t in xy], [t[2] for t in xy] -unzip(xyz::AVec{Tuple{X,Y,Z}}) where {X,Y,Z} = [t[1] for t in xyz], [t[2] for t in xyz], [t[3] for t in xyz] -unzip(xyuv::AVec{Tuple{X,Y,U,V}}) where {X,Y,U,V} = [t[1] for t in xyuv], [t[2] for t in xyuv], [t[3] for t in xyuv], [t[4] for t in xyuv] +for i in 2:4 + @eval begin + unzip(v::Union{AVec{<:Tuple{Vararg{T,$i} where T}}, + AVec{<:GeometryTypes.Point{$i}}}) = $(Expr(:tuple, (:([t[$j] for t in v]) for j=1:i)...)) + end +end -unzip(xy::AVec{GeometryTypes.Point{2,T}}) where {T} = T[t[1] for t in xy], T[t[2] for t in xy] -unzip(xy::GeometryTypes.Point{2,T}) where {T} = T[xy[1]], T[xy[2]] - -unzip(xyz::AVec{GeometryTypes.Point{3,T}}) where {T} = T[t[1] for t in xyz], T[t[2] for t in xyz], T[t[3] for t in xyz] -unzip(xyz::GeometryTypes.Point{3,T}) where {T} = T[xyz[1]], T[xyz[2]], T[xyz[3]] - -unzip(xyuv::AVec{GeometryTypes.Point{4,T}}) where {T} = T[t[1] for t in xyuv], T[t[2] for t in xyuv], T[t[3] for t in xyuv], T[t[4] for t in xyuv] -unzip(xyuv::GeometryTypes.Point{4,T}) where {T} = T[xyuv[1]], T[xyuv[2]], T[xyuv[3]], T[xyuv[4]] +unzip(v::Union{AVec{<:GeometryTypes.Point{N}}, + AVec{<:Tuple{Vararg{T,N} where T}}}) where N = error("$N-dimensional unzip not implemented.") +unzip(v::Union{AVec{<:GeometryTypes.Point}, + AVec{<:Tuple}}) = error("Can't unzip points of different dimensions.") # given 2-element lims and a vector of data x, widen lims to account for the extrema of x function _expand_limits(lims, x) diff --git a/test/runtests.jl b/test/runtests.jl index d5f6864b..0b73b148 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,6 +4,7 @@ using Random using BinaryProvider using Test using FileIO +using GeometryTypes include("imgcomp.jl") # don't actually show the plots @@ -81,3 +82,14 @@ end @test segments([NaN; 1], 1:10) == [2:2, 4:4, 6:6, 8:8, 10:10] @test segments([nan10; 1:15], [1:15; nan10]) == [11:15] end + +@testset "Utils" begin + zipped = ([(1,2)], [("a","b")], [(1,"a"),(2,"b")], + [(1,2),(3,4)], [(1,2,3),(3,4,5)], [(1,2,3,4),(3,4,5,6)], + [(1,2.0),(missing,missing)], [(1,missing),(missing,"a")], + [(missing,missing)], [(missing,missing,missing),("a","b","c")]) + for z in zipped + @test isequal(collect(zip(Plots.unzip(z)...)), z) + @test isequal(collect(zip(Plots.unzip(Point.(z))...)), z) + end +end