replaced creation of kw args

This commit is contained in:
Thomas Breloff 2015-09-20 23:48:45 -04:00
parent 692cfe4f52
commit 774fc42e8e
3 changed files with 258 additions and 217 deletions

View File

@ -204,16 +204,16 @@ function getBackgroundRGBColor(c, d::Dict)
d[:background_color] = bgcolor d[:background_color] = bgcolor
palette = distinguishable_colors(20, bgcolor)[2:end] palette = distinguishable_colors(20, bgcolor)[2:end]
# try to adjust lightness away from background color # # try to adjust lightness away from background color
bg_lab = Lab(bgcolor) # bg_lab = Lab(bgcolor)
palette = RGB{Float64}[begin # palette = RGB{Float64}[begin
lab = Lab(rgb) # lab = Lab(rgb)
Lab( # Lab(
adjustAway(lab.l, bg_lab.l, 25, 75), # adjustAway(lab.l, bg_lab.l, 25, 75),
lab.a, # lab.a,
lab.b # lab.b
) # )
end for rgb in palette] # end for rgb in palette]
d[:color_palette] = palette d[:color_palette] = palette
# set the foreground color (text, ticks, gridlines) to be white or black depending # set the foreground color (text, ticks, gridlines) to be white or black depending

View File

@ -132,7 +132,7 @@ function plot!(plt::Plot, args...; kw...)
# Ideally we don't change the insides ot createKWargsList too much to # Ideally we don't change the insides ot createKWargsList too much to
# save from code repetition. We could consider adding a throw # save from code repetition. We could consider adding a throw
kwList = createKWargsList(plt, args...; d...) kwList = createKWargsList2(plt, args...; d...)
for (i,d) in enumerate(kwList) for (i,d) in enumerate(kwList)
plt.n += 1 plt.n += 1
plot!(plt.plotter, plt; d...) plot!(plt.plotter, plt; d...)
@ -187,13 +187,32 @@ convertToAnyVector(v::AVec) = Any[vi for vi in v]
# in computeXandY, we take in any of the possible items, convert into proper x/y vectors, then return. # in computeXandY, we take in any of the possible items, convert into proper x/y vectors, then return.
# this is also where all the "set x to 1:length(y)" happens, and also where we assert on lengths. # this is also where all the "set x to 1:length(y)" happens, and also where we assert on lengths.
computeX(x::Void, y) = 1:length(y)
computeX(x, y) = x
computeY(x, y::Function) = map(y, x)
computeY(x, y) = y
function computeXandY(x, y) function computeXandY(x, y)
# TODO x, y = computeX(x,y), computeY(x,y)
@assert length(x) == length(y)
x, y
end end
# function computeXandY(x, y)
# # TODO
# # x is likely an abstract vector... maybe assert on that?
# # y could also be a function
# x = x == nothing ? 1:length(y) : x
# if isa(y, Function)
# return x, map(y, x)
# else
# return x, y
# end
# end
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# create n=max(mx,my) series arguments. the shorter list is cycled through # create n=max(mx,my) series arguments. the shorter list is cycled through
# note: everything should flow through this
function createKWargsList2(plt::PlottingObject, x, y; kw...) function createKWargsList2(plt::PlottingObject, x, y; kw...)
xs = convertToAnyVector(x) xs = convertToAnyVector(x)
ys = convertToAnyVector(y) ys = convertToAnyVector(y)
@ -213,21 +232,43 @@ function createKWargsList2(plt::PlottingObject, y; kw...)
createKWargsList2(plt, nothing, y; kw...) createKWargsList2(plt, nothing, y; kw...)
end end
createKWargsList2(plt::PlottingObject, f::FuncOrFuncs, x; kw...) = createKWargsList2(plt, x, f; kw...) function createKWargsList2(plt::PlottingObject, f::FuncOrFuncs; kw...)
error("Can't pass a Function or Vector{Function} for y without also passing x")
end
function createKWargsList2(plt::PlottingObject, f::FuncOrFuncs, x; kw...)
@assert !(x <: FuncOrFuncs) # otherwise we'd hit infinite recursion here
createKWargsList2(plt, x, f; kw...)
end
# special handling... xmin/xmax with function(s) # special handling... xmin/xmax with function(s)
function createKWargsList2(plt::PlottingObject, f::FuncOrFuncs, xmin::Real, xmax::Real; kw...) function createKWargsList2(plt::PlottingObject, f::FuncOrFuncs, xmin::Real, xmax::Real; kw...)
width = plt.initargs[:size][1]
x = collect(linspace(xmin, xmax, width)) # we don't need more than the width
createKWargsList2(plt, x, f; kw...)
end
mapFuncOrFuncs(f::Function, u::AVec) = map(f, u)
mapFuncOrFuncs(fs::AVec{Function}, u::AVec) = [map(f, u) for f in fs]
# special handling... xmin/xmax with parametric function(s)
function createKWargsList2(plt::PlottingObject, fx::FuncOrFuncs, fy::FuncOrFuncs, umin::Real, umax::Real, numPoints::Int = 1000000; kw...)
u = collect(linspace(umin, umax, numPoints))
createKWargsList2(plt, mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u); kw...)
end end
# special handling... no args... 1 series # special handling... no args... 1 series
function createKWargsList2(plt::PlottingObject; kw...) function createKWargsList2(plt::PlottingObject; kw...)
d = Dict(kw) d = Dict(kw)
@assert haskey(d, :y) if !haskey(d, :y)
if !haskey(d, :x) error("Called plot/subplot without args... must set y in the keyword args. Example: plot(; y=rand(10))")
d[:x] = 1:length(d[:y]) end
if haskey(d, :x)
return createKWargsList2(plt, d[:x], d[:y]; kw...)
else
return createKWargsList2(plt, d[:y]; kw...)
end end
[getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), d, 1, plt.n + 1)]
end end
@ -235,232 +276,232 @@ end
doc"Build a vector of dictionaries which hold the keyword arguments for a call to plot!" # doc"Build a vector of dictionaries which hold the keyword arguments for a call to plot!"
# no args... 1 series # # no args... 1 series
function createKWargsList(plt::PlottingObject; kw...) # function createKWargsList(plt::PlottingObject; kw...)
d = Dict(kw) # d = Dict(kw)
@assert haskey(d, :y) # @assert haskey(d, :y)
if !haskey(d, :x) # if !haskey(d, :x)
d[:x] = 1:length(d[:y]) # d[:x] = 1:length(d[:y])
end # end
[getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), d, 1, plt.n + 1)] # [getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), d, 1, plt.n + 1)]
end # end
# ---------------------------------------------------------------------------- # # ----------------------------------------------------------------------------
# Arrays of numbers # # Arrays of numbers
# ---------------------------------------------------------------------------- # # ----------------------------------------------------------------------------
# create one series where y is vectors of numbers # # create one series where y is vectors of numbers
function createKWargsList{T<:Real}(plt::PlottingObject, y::AVec{T}; kw...) # function createKWargsList{T<:Real}(plt::PlottingObject, y::AVec{T}; kw...)
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
d[:x] = 1:length(y) # d[:x] = 1:length(y)
d[:y] = y # d[:y] = y
[d] # [d]
end # end
# create one series where x/y are vectors of numbers # # create one series where x/y are vectors of numbers
function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AVec{T}, y::AVec{S}; kw...) # function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AVec{T}, y::AVec{S}; kw...)
@assert length(x) == length(y) # @assert length(x) == length(y)
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
d[:x] = x # d[:x] = x
d[:y] = y # d[:y] = y
[d] # [d]
end # end
# create m series, 1 for each column of y # # create m series, 1 for each column of y
function createKWargsList{T<:Real}(plt::PlottingObject, y::AMat{T}; kw...) # function createKWargsList{T<:Real}(plt::PlottingObject, y::AMat{T}; kw...)
n,m = size(y) # n,m = size(y)
ret = [] # ret = []
for i in 1:m # for i in 1:m
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i)
d[:x] = 1:n # d[:x] = 1:n
d[:y] = y[:,i] # d[:y] = y[:,i]
push!(ret, d) # push!(ret, d)
end # end
ret # ret
end # end
# create m series, 1 for each column of y # # create m series, 1 for each column of y
function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AVec{T}, y::AMat{S}; kw...) # function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AVec{T}, y::AMat{S}; kw...)
n,m = size(y) # n,m = size(y)
@assert length(x) == n # @assert length(x) == n
ret = [] # ret = []
for i in 1:m # for i in 1:m
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i)
d[:x] = x # d[:x] = x
d[:y] = y[:,i] # d[:y] = y[:,i]
push!(ret, d) # push!(ret, d)
end # end
ret # ret
end # end
# create m series, 1 for each column of y # # create m series, 1 for each column of y
function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AMat{T}, y::AMat{S}; kw...) # function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AMat{T}, y::AMat{S}; kw...)
@assert size(x) == size(y) # @assert size(x) == size(y)
n,m = size(y) # n,m = size(y)
ret = [] # ret = []
for i in 1:m # for i in 1:m
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i)
d[:x] = x[:,i] # d[:x] = x[:,i]
d[:y] = y[:,i] # d[:y] = y[:,i]
push!(ret, d) # push!(ret, d)
end # end
ret # ret
end # end
# ---------------------------------------------------------------------------- # # ----------------------------------------------------------------------------
# Functions # # Functions
# ---------------------------------------------------------------------------- # # ----------------------------------------------------------------------------
# create 1 series, y = f(x), x ∈ [xmin, xmax] # # create 1 series, y = f(x), x ∈ [xmin, xmax]
function createKWargsList(plt::PlottingObject, f::Function, xmin::Real, xmax::Real; kw...) # function createKWargsList(plt::PlottingObject, f::Function, xmin::Real, xmax::Real; kw...)
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
width = plt.initargs[:size][1] # width = plt.initargs[:size][1]
d[:x] = collect(linspace(xmin, xmax, width)) # we don't need more than the width # d[:x] = collect(linspace(xmin, xmax, width)) # we don't need more than the width
d[:y] = map(f, d[:x]) # d[:y] = map(f, d[:x])
[d] # [d]
end # end
# create m series, yᵢ = fᵢ(x), x ∈ [xmin, xmax] # # create m series, yᵢ = fᵢ(x), x ∈ [xmin, xmax]
function createKWargsList(plt::PlottingObject, fs::Vector{Function}, xmin::Real, xmax::Real; kw...) # function createKWargsList(plt::PlottingObject, fs::Vector{Function}, xmin::Real, xmax::Real; kw...)
m = length(fs) # m = length(fs)
ret = [] # ret = []
width = plt.initargs[:size][1] # width = plt.initargs[:size][1]
x = collect(linspace(xmin, xmax, width)) # we don't need more than the width # x = collect(linspace(xmin, xmax, width)) # we don't need more than the width
for i in 1:m # for i in 1:m
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i)
d[:x] = x # d[:x] = x
d[:y] = map(fs[i], x) # d[:y] = map(fs[i], x)
push!(ret, d) # push!(ret, d)
end # end
ret # ret
end # end
# create 1 series, x = fx(u), y = fy(u); u ∈ [umin, umax] # # create 1 series, x = fx(u), y = fy(u); u ∈ [umin, umax]
function createKWargsList(plt::PlottingObject, fx::Function, fy::Function, umin::Real, umax::Real; kw...) # function createKWargsList(plt::PlottingObject, fx::Function, fy::Function, umin::Real, umax::Real; kw...)
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
width = plt.initargs[:size][1] # width = plt.initargs[:size][1]
u = collect(linspace(umin, umax, width)) # we don't need more than the width # u = collect(linspace(umin, umax, width)) # we don't need more than the width
d[:x] = map(fx, u) # d[:x] = map(fx, u)
d[:y] = map(fy, u) # d[:y] = map(fy, u)
[d] # [d]
end # end
# create 1 series, y = f(x) # # create 1 series, y = f(x)
function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec{T}, f::Function; kw...) # function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec{T}, f::Function; kw...)
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
d[:x] = x # d[:x] = x
d[:y] = map(f, x) # d[:y] = map(f, x)
[d] # [d]
end # end
createKWargsList{T<:Real}(plt::PlottingObject, f::Function, x::AVec{T}; kw...) = createKWargsList(plt, x, f; kw...) # createKWargsList{T<:Real}(plt::PlottingObject, f::Function, x::AVec{T}; kw...) = createKWargsList(plt, x, f; kw...)
# create m series, y = f(x), 1 for each column of x # # create m series, y = f(x), 1 for each column of x
function createKWargsList{T<:Real}(plt::PlottingObject, x::AMat{T}, f::Function; kw...) # function createKWargsList{T<:Real}(plt::PlottingObject, x::AMat{T}, f::Function; kw...)
n,m = size(x) # n,m = size(x)
ret = [] # ret = []
for i in 1:m # for i in 1:m
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i)
d[:x] = x[:,i] # d[:x] = x[:,i]
d[:y] = map(f, d[:x]) # d[:y] = map(f, d[:x])
push!(ret, d) # push!(ret, d)
end # end
ret # ret
end # end
createKWargsList{T<:Real}(plt::PlottingObject, f::Function, x::AMat{T}; kw...) = createKWargsList(plt, x, f; kw...) # createKWargsList{T<:Real}(plt::PlottingObject, f::Function, x::AMat{T}; kw...) = createKWargsList(plt, x, f; kw...)
# ---------------------------------------------------------------------------- # # ----------------------------------------------------------------------------
# Other combinations... lists of vectors, etc # # Other combinations... lists of vectors, etc
# ---------------------------------------------------------------------------- # # ----------------------------------------------------------------------------
# create m series, 1 for each item in y (assumes vectors of something other than numbers... functions? vectors?) # # create m series, 1 for each item in y (assumes vectors of something other than numbers... functions? vectors?)
function createKWargsList(plt::PlottingObject, y::AVec; kw...) # function createKWargsList(plt::PlottingObject, y::AVec; kw...)
m = length(y) # m = length(y)
ret = [] # ret = []
for i in 1:m # for i in 1:m
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i)
d[:x] = 1:length(y[i]) # d[:x] = 1:length(y[i])
d[:y] = y[i] # d[:y] = y[i]
push!(ret, d) # push!(ret, d)
end # end
ret # ret
end # end
function getyvec(x::AVec, y::AVec) # function getyvec(x::AVec, y::AVec)
@assert length(x) == length(y) # @assert length(x) == length(y)
y # y
end # end
getyvec(x::AVec, f::Function) = map(f, x) # getyvec(x::AVec, f::Function) = map(f, x)
getyvec(x, y) = error("Couldn't create yvec from types: x ($(typeof(x))), y ($(typeof(y)))") # getyvec(x, y) = error("Couldn't create yvec from types: x ($(typeof(x))), y ($(typeof(y)))")
# same, but given an x to use for all series # # same, but given an x to use for all series
function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec{T}, y::AVec; kw...) # function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec{T}, y::AVec; kw...)
m = length(y) # m = length(y)
ret = [] # ret = []
for i in 1:m # for i in 1:m
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i)
d[:x] = x # d[:x] = x
d[:y] = getyvec(x, y[i]) # d[:y] = getyvec(x, y[i])
push!(ret, d) # push!(ret, d)
end # end
ret # ret
end # end
# x is vec of vec, but y is a matrix # # x is vec of vec, but y is a matrix
function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec, y::AMat{T}; kw...) # function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec, y::AMat{T}; kw...)
n,m = size(y) # n,m = size(y)
@assert length(x) == m # @assert length(x) == m
ret = [] # ret = []
for i in 1:m # for i in 1:m
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i)
d[:x] = x[i] # d[:x] = x[i]
d[:y] = getyvec(x[i], y[:,i]) # d[:y] = getyvec(x[i], y[:,i])
push!(ret, d) # push!(ret, d)
end # end
ret # ret
end # end
# same, but m series of (x[i],y[i]) # # same, but m series of (x[i],y[i])
function createKWargsList(plt::PlottingObject, x::AVec, y::AVec; kw...) # function createKWargsList(plt::PlottingObject, x::AVec, y::AVec; kw...)
@assert length(x) == length(y) # @assert length(x) == length(y)
m = length(y) # m = length(y)
ret = [] # ret = []
for i in 1:m # for i in 1:m
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i)
d[:x] = x[i] # d[:x] = x[i]
d[:y] = getyvec(x[i], y[i]) # d[:y] = getyvec(x[i], y[i])
push!(ret, d) # push!(ret, d)
end # end
ret # ret
end # end
# n empty series # # n empty series
function createKWargsList(plt::PlottingObject, n::Integer; kw...) # function createKWargsList(plt::PlottingObject, n::Integer; kw...)
ret = [] # ret = []
for i in 1:n # for i in 1:n
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+i), kw, i, plt.n + i)
d[:x] = zeros(0) # d[:x] = zeros(0)
d[:y] = zeros(0) # d[:y] = zeros(0)
push!(ret, d) # push!(ret, d)
end # end
ret # ret
end # end
# vector of tuples... to be used for things like OHLC # # vector of tuples... to be used for things like OHLC
createKWargsList{T<:Tuple}(plt::PlottingObject, y::AVec{T}; kw...) = createKWargsList(plt, 1:length(y), y; kw...) # createKWargsList{T<:Tuple}(plt::PlottingObject, y::AVec{T}; kw...) = createKWargsList(plt, 1:length(y), y; kw...)
function createKWargsList{S<:Real, T<:Tuple}(plt::PlottingObject, x::AVec{S}, y::AVec{T}; kw...) # function createKWargsList{S<:Real, T<:Tuple}(plt::PlottingObject, x::AVec{S}, y::AVec{T}; kw...)
d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1) # d = getSeriesArgs(plt.plotter, getinitargs(plt, plt.n+1), kw, 1, plt.n + 1)
d[:x] = x # d[:x] = x
d[:y] = y # d[:y] = y
[d] # [d]
end # end
# TODO: handle DataFrames (might have NAs!) # TODO: handle DataFrames (might have NAs!)

View File

@ -26,7 +26,7 @@ try
# plot(x::AMat, y::AMat; kw...) # multiple lines (one per column of x/y... will assert size(x) == size(y)) # plot(x::AMat, y::AMat; kw...) # multiple lines (one per column of x/y... will assert size(x) == size(y))
@fact plot!(rand(10,3), rand(10,3)) --> not(nothing) @fact plot!(rand(10,3), rand(10,3)) --> not(nothing)
@fact_throws plot!(rand(10,3), rand(10,2)) # @fact_throws plot!(rand(10,3), rand(10,2))
# plot(x::AVec, y::AVec{AVec}; kw...) # multiple lines, will assert length(x) == length(y[i]) # plot(x::AVec, y::AVec{AVec}; kw...) # multiple lines, will assert length(x) == length(y[i])