working on series reorg
This commit is contained in:
parent
eecb5c3754
commit
175ce3613a
@ -40,8 +40,9 @@ const _allTypes = vcat([
|
|||||||
:polygon => :shape,
|
:polygon => :shape,
|
||||||
)
|
)
|
||||||
|
|
||||||
ishistlike(lt::Symbol) = lt in (:hist, :density)
|
like_histogram(linetype::Symbol) = linetype in (:hist, :density)
|
||||||
islinelike(lt::Symbol) = lt in (:line, :path, :steppre, :steppost)
|
like_line(linetype::Symbol) = linetype in (:line, :path, :steppre, :steppost)
|
||||||
|
like_surface(linetype::Symbol) = linetype in (:contour, :heatmap, :surface, :wireframe)
|
||||||
|
|
||||||
|
|
||||||
const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||||
|
|||||||
@ -347,7 +347,7 @@ function _add_series(pkg::PyPlotBackend, plt::Plot; kw...)
|
|||||||
# NOTE: this is unsupported because it does the wrong thing... it shifts the whole axis
|
# NOTE: this is unsupported because it does the wrong thing... it shifts the whole axis
|
||||||
# extra_kwargs[:bottom] = d[:fill]
|
# extra_kwargs[:bottom] = d[:fill]
|
||||||
|
|
||||||
if ishistlike(lt)
|
if like_histogram(lt)
|
||||||
extra_kwargs[:bins] = d[:nbins]
|
extra_kwargs[:bins] = d[:nbins]
|
||||||
extra_kwargs[:normed] = lt == :density
|
extra_kwargs[:normed] = lt == :density
|
||||||
else
|
else
|
||||||
@ -434,7 +434,7 @@ function _add_series(pkg::PyPlotBackend, plt::Plot; kw...)
|
|||||||
end
|
end
|
||||||
|
|
||||||
# do the plot
|
# do the plot
|
||||||
d[:serieshandle] = if ishistlike(lt)
|
d[:serieshandle] = if like_histogram(lt)
|
||||||
plotfunc(d[:y]; extra_kwargs...)[1]
|
plotfunc(d[:y]; extra_kwargs...)[1]
|
||||||
|
|
||||||
elseif lt == :contour
|
elseif lt == :contour
|
||||||
|
|||||||
@ -6,6 +6,23 @@ end
|
|||||||
get_xs(shape::Shape) = Float64[v[1] for v in shape.vertices]
|
get_xs(shape::Shape) = Float64[v[1] for v in shape.vertices]
|
||||||
get_ys(shape::Shape) = Float64[v[2] for v in shape.vertices]
|
get_ys(shape::Shape) = Float64[v[2] for v in shape.vertices]
|
||||||
|
|
||||||
|
function shape_coords(shape::Shape)
|
||||||
|
unzip(shape.vertices)
|
||||||
|
end
|
||||||
|
|
||||||
|
function shape_coords(shapes::AVec{Shape})
|
||||||
|
length(shapes) == 0 && return zeros(0), zeros(0)
|
||||||
|
xs = map(get_xs, shapes)
|
||||||
|
ys = map(get_ys, shapes)
|
||||||
|
x, y = unzip(shapes[1].vertices)
|
||||||
|
for shape in shapes[2:end]
|
||||||
|
tmpx, tmpy = unzip(shape.vertices)
|
||||||
|
x = vcat(x, NaN, tmpx)
|
||||||
|
y = vcat(y, NaN, tmpy)
|
||||||
|
end
|
||||||
|
x, y
|
||||||
|
end
|
||||||
|
|
||||||
"get an array of tuples of points on a circle with radius `r`"
|
"get an array of tuples of points on a circle with radius `r`"
|
||||||
function partialcircle(start_θ, end_θ, n = 20, r=1)
|
function partialcircle(start_θ, end_θ, n = 20, r=1)
|
||||||
@compat(Tuple{Float64,Float64})[(r*cos(u),r*sin(u)) for u in linspace(start_θ, end_θ, n)]
|
@compat(Tuple{Float64,Float64})[(r*cos(u),r*sin(u)) for u in linspace(start_θ, end_θ, n)]
|
||||||
@ -235,8 +252,10 @@ end
|
|||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
abstract AbstractSurface
|
||||||
|
|
||||||
"represents a contour or surface mesh"
|
"represents a contour or surface mesh"
|
||||||
immutable Surface{M<:AMat}
|
immutable Surface{M<:AMat} <: AbstractSurface
|
||||||
# x::AVec
|
# x::AVec
|
||||||
# y::AVec
|
# y::AVec
|
||||||
surf::M
|
surf::M
|
||||||
@ -251,6 +270,12 @@ for f in (:length, :size)
|
|||||||
end
|
end
|
||||||
Base.copy(surf::Surface) = Surface(copy(surf.surf))
|
Base.copy(surf::Surface) = Surface(copy(surf.surf))
|
||||||
|
|
||||||
|
|
||||||
|
"For the case of representing a surface as a function of x/y... can possibly avoid allocations."
|
||||||
|
immutable SurfaceFunction <: AbstractSurface
|
||||||
|
f::Function
|
||||||
|
end
|
||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
|
|
||||||
type OHLC{T<:Real}
|
type OHLC{T<:Real}
|
||||||
|
|||||||
@ -88,7 +88,12 @@ function plot!(plt::Plot, args...; kw...)
|
|||||||
_before_add_series(plt)
|
_before_add_series(plt)
|
||||||
|
|
||||||
# get the list of dictionaries, one per series
|
# get the list of dictionaries, one per series
|
||||||
seriesArgList, xmeta, ymeta = build_series_args(plt, groupargs..., args...; d...)
|
@show groupargs args
|
||||||
|
dumpdict(d, "before process_inputs")
|
||||||
|
process_inputs(plt, d, groupargs..., args...)
|
||||||
|
dumpdict(d, "after process_inputs")
|
||||||
|
seriesArgList, xmeta, ymeta = build_series_args(plt, d)
|
||||||
|
# seriesArgList, xmeta, ymeta = build_series_args(plt, groupargs..., args...; d...)
|
||||||
|
|
||||||
# if we were able to extract guide information from the series inputs, then update the plot
|
# if we were able to extract guide information from the series inputs, then update the plot
|
||||||
# @show xmeta, ymeta
|
# @show xmeta, ymeta
|
||||||
|
|||||||
@ -77,8 +77,9 @@ compute_x(x::Void, y, z) = 1:size(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) = x
|
compute_x(x, y, z) = x
|
||||||
|
|
||||||
|
compute_y(x::Void, y::Function, z) = error()
|
||||||
compute_y(x::Void, y::Void, z) = 1:size(z,2)
|
compute_y(x::Void, y::Void, z) = 1:size(z,2)
|
||||||
compute_y(x::Void, y, z) = 1:size(x,1)
|
# compute_y(x::Void, y, z) = 1:size(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) = y
|
compute_y(x, y, z) = y
|
||||||
|
|
||||||
@ -120,10 +121,14 @@ function build_series_args(plt::AbstractPlot, kw::KW)
|
|||||||
# build the series arg dict
|
# build the series arg dict
|
||||||
numUncounted = pop!(d, :numUncounted, 0)
|
numUncounted = pop!(d, :numUncounted, 0)
|
||||||
n = plt.n + i + numUncounted
|
n = plt.n + i + numUncounted
|
||||||
|
|
||||||
dumpdict(d, "before getSeriesArgs")
|
dumpdict(d, "before getSeriesArgs")
|
||||||
d = getSeriesArgs(plt.backend, getplotargs(plt, n), d, i + numUncounted, convertSeriesIndex(plt, n), n)
|
d = getSeriesArgs(plt.backend, getplotargs(plt, n), d, i + numUncounted, convertSeriesIndex(plt, n), n)
|
||||||
dumpdict(d, "after getSeriesArgs")
|
dumpdict(d, "after getSeriesArgs")
|
||||||
|
|
||||||
|
@show xs[mod1(i,mx)] ys[mod1(i,my)] zs[mod1(i,mz)]
|
||||||
d[:x], d[:y], d[:z] = compute_xyz(xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)])
|
d[:x], d[:y], d[:z] = compute_xyz(xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)])
|
||||||
|
@show d[:x] d[:y] d[:z]
|
||||||
|
|
||||||
# # NOTE: this should be handled by the time it gets here
|
# # NOTE: this should be handled by the time it gets here
|
||||||
# lt = d[:linetype]
|
# lt = d[:linetype]
|
||||||
@ -172,10 +177,21 @@ function build_series_args(plt::AbstractPlot, kw::KW)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
# process_inputs
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
|
# These methods take a plot and the keyword arguments, and processes the input
|
||||||
|
# arguments (x/y/z, group, etc), populating the KW dict with appropriate values.
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# 0 arguments
|
# 0 arguments
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
|
# don't do anything
|
||||||
|
function process_inputs(plt::AbstractPlot, d::KW)
|
||||||
|
end
|
||||||
|
|
||||||
# # TODO: all methods should probably do this... check for (and pop!) x/y/z values if they exist
|
# # TODO: all methods should probably do this... check for (and pop!) x/y/z values if they exist
|
||||||
#
|
#
|
||||||
# function build_series_args(plt::AbstractPlot, d::KW)
|
# function build_series_args(plt::AbstractPlot, d::KW)
|
||||||
@ -205,118 +221,109 @@ end
|
|||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
# no special handling... assume x and z are nothing
|
# no special handling... assume x and z are nothing
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, y)
|
function process_inputs(plt::AbstractPlot, d::KW, y)
|
||||||
build_series_args(plt, d, nothing, y, nothing)
|
d[:y] = y
|
||||||
end
|
end
|
||||||
|
|
||||||
# matrix... is it z or y?
|
# matrix... is it z or y?
|
||||||
function build_series_args{T<:Number}(plt::AbstractPlot, d::KW, mat::AMat{T})
|
function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, mat::AMat{T})
|
||||||
if all3D(d)
|
if all3D(d)
|
||||||
n,m = size(mat)
|
n,m = size(mat)
|
||||||
build_series_args(plt, d, 1:n, 1:m, mat)
|
d[:x], d[:y], d[:z] = 1:n, 1:m, mat
|
||||||
else
|
else
|
||||||
build_series_args(plt, d, nothing, mat, nothing)
|
d[:y] = mat
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# plotting arbitrary shapes/polygons
|
# plotting arbitrary shapes/polygons
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, shape::Shape)
|
function process_inputs(plt::AbstractPlot, d::KW, shape::Shape)
|
||||||
x, y = unzip(shape.vertices)
|
d[:x], d[:y] = shape_coords(shape)
|
||||||
build_series_args(plt, d, x, y; linetype = :shape)
|
d[:linetype] = :shape
|
||||||
end
|
end
|
||||||
|
function process_inputs(plt::AbstractPlot, d::KW, shapes::AVec{Shape})
|
||||||
function shape_coords(shapes::AVec{Shape})
|
d[:x], d[:y] = shape_coords(shapes)
|
||||||
xs = map(get_xs, shapes)
|
d[:linetype] = :shape
|
||||||
ys = map(get_ys, shapes)
|
|
||||||
x, y = unzip(shapes[1].vertices)
|
|
||||||
for shape in shapes[2:end]
|
|
||||||
tmpx, tmpy = unzip(shape.vertices)
|
|
||||||
x = vcat(x, NaN, tmpx)
|
|
||||||
y = vcat(y, NaN, tmpy)
|
|
||||||
end
|
|
||||||
x, y
|
|
||||||
end
|
end
|
||||||
|
function process_inputs(plt::AbstractPlot, d::KW, shapes::AMat{Shape})
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, shapes::AVec{Shape})
|
|
||||||
x, y = shape_coords(shapes)
|
|
||||||
build_series_args(plt, d, x, y; linetype = :shape)
|
|
||||||
end
|
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, shapes::AMat{Shape})
|
|
||||||
x, y = [], []
|
x, y = [], []
|
||||||
for j in 1:size(shapes, 2)
|
for j in 1:size(shapes, 2)
|
||||||
tmpx, tmpy = shape_coords(vec(shapes[:,j]))
|
tmpx, tmpy = shape_coords(vec(shapes[:,j]))
|
||||||
push!(x, tmpx)
|
push!(x, tmpx)
|
||||||
push!(y, tmpy)
|
push!(y, tmpy)
|
||||||
end
|
end
|
||||||
build_series_args(plt, d, x, y; linetype = :shape)
|
d[:x], d[:y] = x, y
|
||||||
|
d[:linetype] = :shape
|
||||||
end
|
end
|
||||||
|
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, f::FuncOrFuncs)
|
|
||||||
build_series_args(plt, d, f, xmin(plt), xmax(plt))
|
# function without range... use the current range of the x-axis
|
||||||
|
function process_inputs(plt::AbstractPlot, d::KW, f::FuncOrFuncs)
|
||||||
|
process_inputs(plt, d, f, xmin(plt), xmax(plt))
|
||||||
end
|
end
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# 2 arguments
|
# 2 arguments
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, x, y)
|
function process_inputs(plt::AbstractPlot, d::KW, x, y)
|
||||||
build_series_args(plt, d, x, y, nothing)
|
d[:x], d[:y] = x, y
|
||||||
end
|
end
|
||||||
|
|
||||||
# list of functions
|
# if functions come first, just swap the order (not to be confused with parametric functions...
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, f::FuncOrFuncs, x)
|
# as there would be more than one function passed in)
|
||||||
|
function process_inputs(plt::AbstractPlot, d::KW, f::FuncOrFuncs, x)
|
||||||
@assert !(typeof(x) <: FuncOrFuncs) # otherwise we'd hit infinite recursion here
|
@assert !(typeof(x) <: FuncOrFuncs) # otherwise we'd hit infinite recursion here
|
||||||
build_series_args(plt, d, x, f)
|
process_inputs(plt, d, x, f)
|
||||||
end
|
end
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# 3 arguments
|
# 3 arguments
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
|
# no special handling... just pass them through
|
||||||
|
function process_inputs(plt::AbstractPlot, d::KW, x, y, z)
|
||||||
|
d[:x], d[:y], d[:z] = x, y, z
|
||||||
|
end
|
||||||
|
|
||||||
# 3d line or scatter
|
# 3d line or scatter
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, x::AVec, y::AVec, zvec::AVec)
|
function process_inputs(plt::AbstractPlot, d::KW, x::AVec, y::AVec, zvec::AVec)
|
||||||
d = KW(kw)
|
# default to path3d if we haven't set a 3d linetype
|
||||||
if !(get(d, :linetype, :none) in _3dTypes)
|
if !(get(d, :linetype, :none) in _3dTypes)
|
||||||
d[:linetype] = :path3d
|
d[:linetype] = :path3d
|
||||||
end
|
end
|
||||||
build_series_args(plt, d, x, y; z=zvec, d...)
|
d[:x], d[:y], d[:z] = x, y, z
|
||||||
end
|
end
|
||||||
|
|
||||||
# contours or surfaces... function grid
|
# surface-like... function
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, x::AVec, y::AVec, zf::Function)
|
function process_inputs(plt::AbstractPlot, d::KW, x::AVec, y::AVec, zf::Function)
|
||||||
# only allow sorted x/y for now
|
x, y = sort(x), sort(y)
|
||||||
# TODO: auto sort x/y/z properly
|
d[:z] = Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported
|
||||||
@assert x == sort(x)
|
d[:x], d[:y] = x, y
|
||||||
@assert y == sort(y)
|
|
||||||
surface = Float64[zf(xi, yi) for xi in x, yi in y]
|
|
||||||
build_series_args(plt, d, x, y, surface) # passes it to the zmat version
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# contours or surfaces... matrix grid
|
# surface-like... matrix grid
|
||||||
function build_series_args{T<:Number}(plt::AbstractPlot, x::AVec, y::AVec, zmat::AMat{T})
|
function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, x::AVec, y::AVec, zmat::AMat{T})
|
||||||
# only allow sorted x/y for now
|
|
||||||
# TODO: auto sort x/y/z properly
|
|
||||||
@assert x == sort(x)
|
|
||||||
@assert y == sort(y)
|
|
||||||
@assert size(zmat) == (length(x), length(y))
|
@assert size(zmat) == (length(x), length(y))
|
||||||
d = KW(kw)
|
if !issorted(x) || !issorted(y)
|
||||||
d[:z] = Surface(convert(Matrix{Float64}, zmat))
|
x_idx = sortperm(x)
|
||||||
if !(get(d, :linetype, :none) in (:contour, :heatmap, :surface, :wireframe))
|
y_idx = sortperm(y)
|
||||||
|
x, y = x[x_idx], y[y_idx]
|
||||||
|
zmat = z[x_idx, y_idx]
|
||||||
|
end
|
||||||
|
d[:x], d[:y], d[:z] = x, y, Surface{Matrix{Float64}}(zmat)
|
||||||
|
if !like_surface(get(d, :linetype, :none))
|
||||||
d[:linetype] = :contour
|
d[:linetype] = :contour
|
||||||
end
|
end
|
||||||
build_series_args(plt, d, x, y; d...) #, z = surf)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# contours or surfaces... general x, y grid
|
# surfaces-like... general x, y grid
|
||||||
function build_series_args{T<:Number}(plt::AbstractPlot, x::AMat{T}, y::AMat{T}, zmat::AMat{T})
|
function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, x::AMat{T}, y::AMat{T}, zmat::AMat{T})
|
||||||
@assert size(zmat) == size(x) == size(y)
|
@assert size(zmat) == size(x) == size(y)
|
||||||
surf = Surface(convert(Matrix{Float64}, zmat))
|
d[:x], d[:y], d[:z] = Any[x], Any[y], Surface{Matrix{Float64}}(zmat)
|
||||||
d = KW(kw)
|
if !like_surface(get(d, :linetype, :none))
|
||||||
d[:z] = Surface(convert(Matrix{Float64}, zmat))
|
|
||||||
if !(get(d, :linetype, :none) in (:contour, :heatmap, :surface, :wireframe))
|
|
||||||
d[:linetype] = :contour
|
d[:linetype] = :contour
|
||||||
end
|
end
|
||||||
build_series_args(plt, d, Any[x], Any[y]; d...) #kw..., z = surf, linetype = :contour)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -325,57 +332,74 @@ end
|
|||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
# special handling... xmin/xmax with function(s)
|
# special handling... xmin/xmax with function(s)
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, f::FuncOrFuncs, xmin::Number, xmax::Number)
|
function process_inputs(plt::AbstractPlot, d::KW, f::FuncOrFuncs, xmin::Number, xmax::Number)
|
||||||
width = get(plt.plotargs, :size, (100,))[1]
|
width = get(plt.plotargs, :size, (100,))[1]
|
||||||
x = collect(linspace(xmin, xmax, width)) # we don't need more than the width
|
x = linspace(xmin, xmax, width)
|
||||||
build_series_args(plt, d, x, f)
|
process_inputs(plt, d, x, f)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# special handling... xmin/xmax with parametric function(s)
|
# special handling... xmin/xmax with parametric function(s)
|
||||||
build_series_args{T<:Number}(plt::AbstractPlot, fx::FuncOrFuncs, fy::FuncOrFuncs, u::AVec{T}) = build_series_args(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u))
|
process_inputs{T<:Number}(plt::AbstractPlot, fx::FuncOrFuncs, fy::FuncOrFuncs, u::AVec{T}) = process_inputs(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u))
|
||||||
build_series_args{T<:Number}(plt::AbstractPlot, u::AVec{T}, fx::FuncOrFuncs, fy::FuncOrFuncs) = build_series_args(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u))
|
process_inputs{T<:Number}(plt::AbstractPlot, u::AVec{T}, fx::FuncOrFuncs, fy::FuncOrFuncs) = process_inputs(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u))
|
||||||
build_series_args(plt::AbstractPlot, d::KW, fx::FuncOrFuncs, fy::FuncOrFuncs, umin::Number, umax::Number, numPoints::Int = 1000) = build_series_args(plt, d, fx, fy, linspace(umin, umax, numPoints))
|
process_inputs(plt::AbstractPlot, d::KW, fx::FuncOrFuncs, fy::FuncOrFuncs, umin::Number, umax::Number, numPoints::Int = 1000) = process_inputs(plt, d, fx, fy, linspace(umin, umax, numPoints))
|
||||||
|
|
||||||
# special handling... 3D parametric function(s)
|
# special handling... 3D parametric function(s)
|
||||||
build_series_args{T<:Number}(plt::AbstractPlot, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs, u::AVec{T}) = build_series_args(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u))
|
process_inputs{T<:Number}(plt::AbstractPlot, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs, u::AVec{T}) = process_inputs(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u))
|
||||||
build_series_args{T<:Number}(plt::AbstractPlot, u::AVec{T}, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs) = build_series_args(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u))
|
process_inputs{T<:Number}(plt::AbstractPlot, u::AVec{T}, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs) = process_inputs(plt, d, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u))
|
||||||
build_series_args(plt::AbstractPlot, d::KW, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs, umin::Number, umax::Number, numPoints::Int = 1000) = build_series_args(plt, d, fx, fy, fz, linspace(umin, umax, numPoints))
|
process_inputs(plt::AbstractPlot, d::KW, fx::FuncOrFuncs, fy::FuncOrFuncs, fz::FuncOrFuncs, umin::Number, umax::Number, numPoints::Int = 1000) = process_inputs(plt, d, fx, fy, fz, linspace(umin, umax, numPoints))
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# Lists of tuples and FixedSizeArrays
|
# Lists of tuples and FixedSizeArrays
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
|
# if we get an unhandled tuple, just splat it in
|
||||||
|
function process_inputs(plt::AbstractPlot, d::KW, tup::Tuple)
|
||||||
|
process_inputs(plt, d, tup...)
|
||||||
|
end
|
||||||
|
|
||||||
# (x,y) tuples
|
# (x,y) tuples
|
||||||
function build_series_args{R1<:Number,R2<:Number}(plt::AbstractPlot, xy::AVec{Tuple{R1,R2}})
|
function process_inputs{R1<:Number,R2<:Number}(plt::AbstractPlot, d::KW, xy::AVec{Tuple{R1,R2}})
|
||||||
build_series_args(plt, d, unzip(xy)...)
|
process_inputs(plt, d, unzip(xy)...)
|
||||||
end
|
end
|
||||||
function build_series_args{R1<:Number,R2<:Number}(plt::AbstractPlot, xy::Tuple{R1,R2})
|
function process_inputs{R1<:Number,R2<:Number}(plt::AbstractPlot, d::KW, xy::Tuple{R1,R2})
|
||||||
build_series_args(plt, d, [xy[1]], [xy[2]])
|
process_inputs(plt, d, [xy[1]], [xy[2]])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# (x,y,z) tuples
|
||||||
unzip{T}(x::AVec{FixedSizeArrays.Vec{2,T}}) = T[xi[1] for xi in x], T[xi[2] for xi in x]
|
function process_inputs{R1<:Number,R2<:Number,R3<:Number}(plt::AbstractPlot, d::KW, xyz::AVec{Tuple{R1,R2,R3}})
|
||||||
unzip{T}(x::FixedSizeArrays.Vec{2,T}) = T[x[1]], T[x[2]]
|
process_inputs(plt, d, unzip(xyz)...)
|
||||||
|
end
|
||||||
function build_series_args{T<:Number}(plt::AbstractPlot, xy::AVec{FixedSizeArrays.Vec{2,T}})
|
function process_inputs{R1<:Number,R2<:Number,R3<:Number}(plt::AbstractPlot, d::KW, xyz::Tuple{R1,R2,R3})
|
||||||
build_series_args(plt, d, unzip(xy)...)
|
process_inputs(plt, d, [xyz[1]], [xyz[2]], [xyz[3]])
|
||||||
end
|
end
|
||||||
|
|
||||||
function build_series_args{T<:Number}(plt::AbstractPlot, xy::FixedSizeArrays.Vec{2,T})
|
# 2D FixedSizeArrays
|
||||||
build_series_args(plt, d, [xy[1]], [xy[2]])
|
function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, xy::AVec{FixedSizeArrays.Vec{2,T}})
|
||||||
|
process_inputs(plt, d, unzip(xy)...)
|
||||||
|
end
|
||||||
|
function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, xy::FixedSizeArrays.Vec{2,T})
|
||||||
|
process_inputs(plt, d, [xy[1]], [xy[2]])
|
||||||
|
end
|
||||||
|
|
||||||
|
# 3D FixedSizeArrays
|
||||||
|
function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, xyz::AVec{FixedSizeArrays.Vec{3,T}})
|
||||||
|
process_inputs(plt, d, unzip(xyz)...)
|
||||||
|
end
|
||||||
|
function process_inputs{T<:Number}(plt::AbstractPlot, d::KW, xyz::FixedSizeArrays.Vec{3,T})
|
||||||
|
process_inputs(plt, d, [xyz[1]], [xyz[2]], [xyz[3]])
|
||||||
end
|
end
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# handle grouping
|
# handle grouping
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, groupby::GroupBy, args...)
|
function process_inputs(plt::AbstractPlot, d::KW, groupby::GroupBy, args...)
|
||||||
ret = Any[]
|
ret = Any[]
|
||||||
|
error("unfinished after series reorg")
|
||||||
for (i,glab) in enumerate(groupby.groupLabels)
|
for (i,glab) in enumerate(groupby.groupLabels)
|
||||||
# TODO: don't automatically overwrite labels
|
# TODO: don't automatically overwrite labels
|
||||||
kwlist, xmeta, ymeta = build_series_args(plt, d, args...,
|
kwlist, xmeta, ymeta = process_inputs(plt, d, args...,
|
||||||
idxfilter = groupby.groupIds[i],
|
idxfilter = groupby.groupIds[i],
|
||||||
label = string(glab),
|
label = string(glab),
|
||||||
numUncounted = length(ret)) # we count the idx from plt.n + numUncounted + i
|
numUncounted = length(ret)) # we count the idx from plt.n + numUncounted + i
|
||||||
@ -391,8 +415,13 @@ end
|
|||||||
function setup_dataframes()
|
function setup_dataframes()
|
||||||
@require DataFrames begin
|
@require DataFrames begin
|
||||||
|
|
||||||
function build_series_args(plt::AbstractPlot, d::KW, df::DataFrames.AbstractDataFrame, args...)
|
# function process_inputs(plt::AbstractPlot, d::KW, df::DataFrames.AbstractDataFrame, args...)
|
||||||
build_series_args(plt, d, args..., dataframe = df)
|
# process_inputs(plt, d, args..., dataframe = df)
|
||||||
|
# end
|
||||||
|
|
||||||
|
function process_inputs(plt::AbstractPlot, d::KW, df::DataFrames.AbstractDataFrame, args...)
|
||||||
|
d[:dataframe] = df
|
||||||
|
process_inputs(plt, d, args...)
|
||||||
end
|
end
|
||||||
|
|
||||||
# expecting the column name of a dataframe that was passed in... anything else should error
|
# expecting the column name of a dataframe that was passed in... anything else should error
|
||||||
|
|||||||
@ -209,8 +209,9 @@ function subplot!(subplt::Subplot, args...; kw...)
|
|||||||
delete!(d, :group)
|
delete!(d, :group)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
process_inputs(subplt, d, groupargs..., args...)
|
||||||
kwList, xmeta, ymeta = build_series_args(subplt, groupargs..., args...; d...)
|
kwList, xmeta, ymeta = build_series_args(subplt, d)
|
||||||
|
# kwList, xmeta, ymeta = build_series_args(subplt, groupargs..., args...; d...)
|
||||||
|
|
||||||
# TODO: something useful with meta info?
|
# TODO: something useful with meta info?
|
||||||
|
|
||||||
|
|||||||
104
src/utils.jl
104
src/utils.jl
@ -121,19 +121,24 @@ nop() = nothing
|
|||||||
|
|
||||||
get_mod(v::AVec, idx::Int) = v[mod1(idx, length(v))]
|
get_mod(v::AVec, idx::Int) = v[mod1(idx, length(v))]
|
||||||
get_mod(v::AMat, idx::Int) = size(v,1) == 1 ? v[1, mod1(idx, size(v,2))] : v[:, mod1(idx, size(v,2))]
|
get_mod(v::AMat, idx::Int) = size(v,1) == 1 ? v[1, mod1(idx, size(v,2))] : v[:, mod1(idx, size(v,2))]
|
||||||
get_mod(v, idx::Int) = v
|
get_mod(v, idx::Int) = v
|
||||||
|
|
||||||
makevec(v::AVec) = v
|
makevec(v::AVec) = v
|
||||||
makevec{T}(v::T) = T[v]
|
makevec{T}(v::T) = T[v]
|
||||||
|
|
||||||
"duplicate a single value, or pass the 2-tuple through"
|
"duplicate a single value, or pass the 2-tuple through"
|
||||||
maketuple(x::Real) = (x,x)
|
maketuple(x::Real) = (x,x)
|
||||||
maketuple{T,S}(x::@compat(Tuple{T,S})) = x
|
maketuple{T,S}(x::@compat(Tuple{T,S})) = x
|
||||||
|
|
||||||
mapFuncOrFuncs(f::Function, u::AVec) = map(f, u)
|
mapFuncOrFuncs(f::Function, u::AVec) = map(f, u)
|
||||||
mapFuncOrFuncs(fs::AVec{Function}, u::AVec) = [map(f, u) for f in fs]
|
mapFuncOrFuncs(fs::AVec{Function}, u::AVec) = [map(f, u) for f in fs]
|
||||||
|
|
||||||
unzip{T,S}(v::AVec{@compat(Tuple{T,S})}) = [vi[1] for vi in v], [vi[2] for vi in v]
|
unzip{T,S}(xy::AVec{Tuple{T,S}}) = [x[1] for x in xy], [y[2] for y in xy]
|
||||||
|
unzip{T,S,R}(xyz::AVec{Tuple{T,S,R}}) = [x[1] for x in xyz], [y[2] for y in xyz], [z[3] for z in xyz]
|
||||||
|
unzip{T}(xy::AVec{FixedSizeArrays.Vec{2,T}}) = T[x[1] for x in xy], T[y[2] for y in xy]
|
||||||
|
unzip{T}(xy::FixedSizeArrays.Vec{2,T}) = T[xy[1]], T[xy[2]]
|
||||||
|
unzip{T}(xyz::AVec{FixedSizeArrays.Vec{3,T}}) = T[x[1] for x in xyz], T[y[2] for y in xyz], T[z[3] for z in xyz]
|
||||||
|
unzip{T}(xyz::FixedSizeArrays.Vec{3,T}) = T[xyz[1]], T[xyz[2]], T[xyz[3]]
|
||||||
|
|
||||||
# given 2-element lims and a vector of data x, widen lims to account for the extrema of x
|
# given 2-element lims and a vector of data x, widen lims to account for the extrema of x
|
||||||
function _expand_limits(lims, x)
|
function _expand_limits(lims, x)
|
||||||
@ -203,29 +208,29 @@ isijulia() = isdefined(Main, :IJulia) && Main.IJulia.inited
|
|||||||
isatom() = isdefined(Main, :Atom) && Atom.isconnected()
|
isatom() = isdefined(Main, :Atom) && Atom.isconnected()
|
||||||
|
|
||||||
istuple(::Tuple) = true
|
istuple(::Tuple) = true
|
||||||
istuple(::Any) = false
|
istuple(::Any) = false
|
||||||
isvector(::AVec) = true
|
isvector(::AVec) = true
|
||||||
isvector(::Any) = false
|
isvector(::Any) = false
|
||||||
ismatrix(::AMat) = true
|
ismatrix(::AMat) = true
|
||||||
ismatrix(::Any) = false
|
ismatrix(::Any) = false
|
||||||
isscalar(::Real) = true
|
isscalar(::Real) = true
|
||||||
isscalar(::Any) = false
|
isscalar(::Any) = false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ticksType{T<:Real,S<:Real}(ticks::@compat(Tuple{T,S})) = :limits
|
# ticksType{T<:Real,S<:Real}(ticks::@compat(Tuple{T,S})) = :limits
|
||||||
ticksType{T<:Real}(ticks::AVec{T}) = :ticks
|
ticksType{T<:Real}(ticks::AVec{T}) = :ticks
|
||||||
ticksType{T<:AbstractString}(ticks::AVec{T}) = :labels
|
ticksType{T<:AbstractString}(ticks::AVec{T}) = :labels
|
||||||
ticksType{T<:AVec,S<:AVec}(ticks::@compat(Tuple{T,S})) = :ticks_and_labels
|
ticksType{T<:AVec,S<:AVec}(ticks::@compat(Tuple{T,S})) = :ticks_and_labels
|
||||||
ticksType(ticks) = :invalid
|
ticksType(ticks) = :invalid
|
||||||
|
|
||||||
limsType{T<:Real,S<:Real}(lims::@compat(Tuple{T,S})) = :limits
|
limsType{T<:Real,S<:Real}(lims::@compat(Tuple{T,S})) = :limits
|
||||||
limsType(lims::Symbol) = lims == :auto ? :auto : :invalid
|
limsType(lims::Symbol) = lims == :auto ? :auto : :invalid
|
||||||
limsType(lims) = :invalid
|
limsType(lims) = :invalid
|
||||||
|
|
||||||
|
|
||||||
Base.convert{T<:Real}(::Type{Vector{T}}, rng::Range{T}) = T[x for x in rng]
|
Base.convert{T<:Real}(::Type{Vector{T}}, rng::Range{T}) = T[x for x in rng]
|
||||||
Base.convert{T<:Real,S<:Real}(::Type{Vector{T}}, rng::Range{S}) = T[x for x in rng]
|
Base.convert{T<:Real,S<:Real}(::Type{Vector{T}}, rng::Range{S}) = T[x for x in rng]
|
||||||
|
|
||||||
Base.merge(a::AbstractVector, b::AbstractVector) = sort(unique(vcat(a,b)))
|
Base.merge(a::AbstractVector, b::AbstractVector) = sort(unique(vcat(a,b)))
|
||||||
@ -238,14 +243,14 @@ wraptuple(x) = (x,)
|
|||||||
trueOrAllTrue(f::Function, x::AbstractArray) = all(f, x)
|
trueOrAllTrue(f::Function, x::AbstractArray) = all(f, x)
|
||||||
trueOrAllTrue(f::Function, x) = f(x)
|
trueOrAllTrue(f::Function, x) = f(x)
|
||||||
|
|
||||||
allLineTypes(arg) = trueOrAllTrue(a -> get(_typeAliases, a, a) in _allTypes, arg)
|
allLineTypes(arg) = trueOrAllTrue(a -> get(_typeAliases, a, a) in _allTypes, arg)
|
||||||
allStyles(arg) = trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
|
allStyles(arg) = trueOrAllTrue(a -> get(_styleAliases, a, a) in _allStyles, arg)
|
||||||
allShapes(arg) = trueOrAllTrue(a -> get(_markerAliases, a, a) in _allMarkers, arg) ||
|
allShapes(arg) = trueOrAllTrue(a -> get(_markerAliases, a, a) in _allMarkers, arg) ||
|
||||||
trueOrAllTrue(a -> isa(a, Shape), arg)
|
trueOrAllTrue(a -> isa(a, Shape), arg)
|
||||||
allAlphas(arg) = trueOrAllTrue(a -> (typeof(a) <: Real && a > 0 && a < 1) ||
|
allAlphas(arg) = trueOrAllTrue(a -> (typeof(a) <: Real && a > 0 && a < 1) ||
|
||||||
(typeof(a) <: AbstractFloat && (a == zero(typeof(a)) || a == one(typeof(a)))), arg)
|
(typeof(a) <: AbstractFloat && (a == zero(typeof(a)) || a == one(typeof(a)))), arg)
|
||||||
allReals(arg) = trueOrAllTrue(a -> typeof(a) <: Real, arg)
|
allReals(arg) = trueOrAllTrue(a -> typeof(a) <: Real, arg)
|
||||||
allFunctions(arg) = trueOrAllTrue(a -> isa(a, Function), arg)
|
allFunctions(arg) = trueOrAllTrue(a -> isa(a, Function), arg)
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
|
|
||||||
@ -429,11 +434,11 @@ end
|
|||||||
# used in updating an existing series
|
# used in updating an existing series
|
||||||
|
|
||||||
extendSeriesByOne(v::UnitRange{Int}, n::Int = 1) = isempty(v) ? (1:n) : (minimum(v):maximum(v)+n)
|
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) + maximum(v))
|
extendSeriesByOne(v::AVec, n::Integer = 1) = isempty(v) ? (1:n) : vcat(v, (1:n) + maximum(v))
|
||||||
extendSeriesData{T}(v::Range{T}, z::Real) = extendSeriesData(float(collect(v)), z)
|
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::Range{T}, z::AVec) = extendSeriesData(float(collect(v)), z)
|
||||||
extendSeriesData{T}(v::AVec{T}, z::Real) = (push!(v, convert(T, z)); v)
|
extendSeriesData{T}(v::AVec{T}, z::Real) = (push!(v, convert(T, z)); v)
|
||||||
extendSeriesData{T}(v::AVec{T}, z::AVec) = (append!(v, convert(Vector{T}, z)); v)
|
extendSeriesData{T}(v::AVec{T}, z::AVec) = (append!(v, convert(Vector{T}, z)); v)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
@ -453,22 +458,15 @@ function supportGraph(allvals, func)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
n = length(vals)
|
n = length(vals)
|
||||||
|
scatter(x, y, m=:rect, ms=10, size=(300,100+18*n), leg=false)
|
||||||
scatter(x,y,
|
|
||||||
m=:rect,
|
|
||||||
ms=10,
|
|
||||||
size=(300,100+18*n),
|
|
||||||
# xticks=(collect(1:length(bs)), bs),
|
|
||||||
leg=false
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
supportGraphArgs() = supportGraph(_allArgs, supportedArgs)
|
supportGraphArgs() = supportGraph(_allArgs, supportedArgs)
|
||||||
supportGraphTypes() = supportGraph(_allTypes, supportedTypes)
|
supportGraphTypes() = supportGraph(_allTypes, supportedTypes)
|
||||||
supportGraphStyles() = supportGraph(_allStyles, supportedStyles)
|
supportGraphStyles() = supportGraph(_allStyles, supportedStyles)
|
||||||
supportGraphMarkers() = supportGraph(_allMarkers, supportedMarkers)
|
supportGraphMarkers() = supportGraph(_allMarkers, supportedMarkers)
|
||||||
supportGraphScales() = supportGraph(_allScales, supportedScales)
|
supportGraphScales() = supportGraph(_allScales, supportedScales)
|
||||||
supportGraphAxes() = supportGraph(_allAxes, supportedAxes)
|
supportGraphAxes() = supportGraph(_allAxes, supportedAxes)
|
||||||
|
|
||||||
function dumpSupportGraphs()
|
function dumpSupportGraphs()
|
||||||
for func in (supportGraphArgs, supportGraphTypes, supportGraphStyles,
|
for func in (supportGraphArgs, supportGraphTypes, supportGraphStyles,
|
||||||
@ -483,16 +481,18 @@ end
|
|||||||
|
|
||||||
# Some conversion functions
|
# Some conversion functions
|
||||||
# note: I borrowed these conversion constants from Compose.jl's Measure
|
# note: I borrowed these conversion constants from Compose.jl's Measure
|
||||||
const PX_PER_INCH = 100
|
|
||||||
const DPI = PX_PER_INCH
|
const PX_PER_INCH = 100
|
||||||
const MM_PER_INCH = 25.4
|
const DPI = PX_PER_INCH
|
||||||
const MM_PER_PX = MM_PER_INCH / PX_PER_INCH
|
const MM_PER_INCH = 25.4
|
||||||
inch2px(inches::Real) = float(inches * PX_PER_INCH)
|
const MM_PER_PX = MM_PER_INCH / PX_PER_INCH
|
||||||
px2inch(px::Real) = float(px / PX_PER_INCH)
|
|
||||||
inch2mm(inches::Real) = float(inches * MM_PER_INCH)
|
inch2px(inches::Real) = float(inches * PX_PER_INCH)
|
||||||
mm2inch(mm::Real) = float(mm / MM_PER_INCH)
|
px2inch(px::Real) = float(px / PX_PER_INCH)
|
||||||
px2mm(px::Real) = float(px * MM_PER_PX)
|
inch2mm(inches::Real) = float(inches * MM_PER_INCH)
|
||||||
mm2px(mm::Real) = float(px / MM_PER_PX)
|
mm2inch(mm::Real) = float(mm / MM_PER_INCH)
|
||||||
|
px2mm(px::Real) = float(px * MM_PER_PX)
|
||||||
|
mm2px(mm::Real) = float(px / MM_PER_PX)
|
||||||
|
|
||||||
|
|
||||||
"Smallest x in plot"
|
"Smallest x in plot"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user