working on auto-labels from dataframes meta info, and started group arg

This commit is contained in:
Thomas Breloff 2015-09-23 15:34:42 -04:00
parent 22fd25b30f
commit 75f4ca928f
2 changed files with 71 additions and 20 deletions

View File

@ -249,6 +249,24 @@ function plotDefault!(k::Symbol, v)
end end
end end
# -----------------------------------------------------------------------------
"A special type that will break up incoming data into groups, and allow for easier creation of grouped plots"
type GroupBy
numGroups::Int
numPoints::Int
groupLabels::Vector{UTF8String} # length == numGroups
groupIds::Vector{Int} # length == numPoints
end
function extractGroupArgs(d::Dict)
# expecting a mapping of "group label" to "group indices"
end
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
function warnOnUnsupportedArgs(pkg::PlottingPackage, d::Dict) function warnOnUnsupportedArgs(pkg::PlottingPackage, d::Dict)

View File

@ -88,16 +88,27 @@ function plot!(plt::Plot, args...; kw...)
# index partitions/filters to be passed through to the next step. # index partitions/filters to be passed through to the next step.
# 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
groupargs = haskey(d, :group) ? extractGroupArgs(d[:group]) : []
@show groupargs
# just in case the backend needs to set up the plot (make it current or something) # just in case the backend needs to set up the plot (make it current or something)
preparePlotUpdate(plt) preparePlotUpdate(plt)
kwList = createKWargsList(plt, args...; d...) # get the list of dictionaries, one per series
for (i,d) in enumerate(kwList) kwList, xmeta, ymeta = createKWargsList(plt, groupargs..., args...; d...)
@show xmeta ymeta typeof(xmeta) typeof(ymeta)
# if we were able to extract guide information from the series inputs, then update the plot
updateDictWithMeta(d, plt.initargs, xmeta, true)
updateDictWithMeta(d, plt.initargs, ymeta, false)
# now we can plot the series
for (i,di) in enumerate(kwList)
plt.n += 1 plt.n += 1
plot!(plt.plotter, plt; d...) plot!(plt.plotter, plt; di...)
end end
#
updatePlotItems(plt, d) updatePlotItems(plt, d)
currentPlot!(plt) currentPlot!(plt)
@ -112,10 +123,16 @@ end
preparePlotUpdate(plt::Plot) = nothing preparePlotUpdate(plt::Plot) = nothing
# # show/update the plot
# function Base.display(plt::PlottingObject) # should we update the x/y label given the meta info during input slicing?
# display(plt.plotter, plt) function updateDictWithMeta(d::Dict, initargs::Dict, meta::Symbol, isx::Bool)
# end lsym = isx ? :xlabel : :ylabel
if initargs[lsym] == plotDefault(lsym)
d[lsym] = string(meta)
end
end
updateDictWithMeta(d::Dict, initargs::Dict, meta, isx::Bool) = nothing
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@ -124,29 +141,30 @@ preparePlotUpdate(plt::Plot) = nothing
# Special handling for: no args, xmin/xmax, parametric, dataframes # Special handling for: no args, xmin/xmax, parametric, dataframes
# Then once inputs have been converted, build the series args, map functions, etc. # Then once inputs have been converted, build the series args, map functions, etc.
# This should cut down on boilerplate code and allow more focused dispatch on type # This should cut down on boilerplate code and allow more focused dispatch on type
# note: returns meta information... mainly for use with automatic labeling from DataFrames for now
typealias FuncOrFuncs Union{Function, AVec{Function}} typealias FuncOrFuncs Union{Function, AVec{Function}}
# missing # missing
convertToAnyVector(v::Void; kw...) = Any[nothing] convertToAnyVector(v::Void; kw...) = Any[nothing], nothing
# fixed number of blank series # fixed number of blank series
convertToAnyVector(n::Integer; kw...) = Any[zero(0) for i in 1:n] convertToAnyVector(n::Integer; kw...) = Any[zero(0) for i in 1:n], nothing
# numeric vector # numeric vector
convertToAnyVector{T<:Real}(v::AVec{T}; kw...) = Any[v] convertToAnyVector{T<:Real}(v::AVec{T}; kw...) = Any[v], nothing
# numeric matrix # numeric matrix
convertToAnyVector{T<:Real}(v::AMat{T}; kw...) = Any[v[:,i] for i in 1:size(v,2)] convertToAnyVector{T<:Real}(v::AMat{T}; kw...) = Any[v[:,i] for i in 1:size(v,2)], nothing
# function # function
convertToAnyVector(f::Function; kw...) = Any[f] convertToAnyVector(f::Function; kw...) = Any[f], nothing
# vector of OHLC # vector of OHLC
convertToAnyVector(v::AVec{OHLC}; kw...) = Any[v] convertToAnyVector(v::AVec{OHLC}; kw...) = Any[v], nothing
# list of things (maybe other vectors, functions, or something else) # list of things (maybe other vectors, functions, or something else)
convertToAnyVector(v::AVec; kw...) = Any[vi for vi in v] convertToAnyVector(v::AVec; kw...) = Any[vi for vi in v], nothing
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@ -169,16 +187,29 @@ 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 # note: everything should flow through this
function createKWargsList(plt::PlottingObject, x, y; kw...) function createKWargsList(plt::PlottingObject, x, y; kw...)
xs = convertToAnyVector(x; kw...) xs, xmeta = convertToAnyVector(x; kw...)
ys = convertToAnyVector(y; kw...) ys, ymeta = convertToAnyVector(y; kw...)
mx = length(xs) mx = length(xs)
my = length(ys) my = length(ys)
ret = [] ret = []
for i in 1:max(mx, my) for i in 1:max(mx, my)
# try to set labels using ymeta
d = Dict(kw)
if !haskey(d, :label) && ymeta != nothing
if isa(ymeta, Symbol)
d[:label] = string(ymeta)
elseif isa(ymeta, AVec{Symbol})
d[:label] = string(ymeta[mod1(i,length(ymeta))])
end
end
# build the series arg dict
n = plt.n + i n = plt.n + i
d = getSeriesArgs(plt.plotter, getinitargs(plt, n), kw, i, convertSeriesIndex(plt, n), n) d = getSeriesArgs(plt.plotter, getinitargs(plt, n), d, i, convertSeriesIndex(plt, n), n)
d[:x], d[:y] = computeXandY(xs[mod1(i,mx)], ys[mod1(i,my)]) d[:x], d[:y] = computeXandY(xs[mod1(i,mx)], ys[mod1(i,my)])
# for linetype `line`, need to sort by x values
if d[:linetype] == :line if d[:linetype] == :line
# order by x # order by x
indices = sortperm(d[:x]) indices = sortperm(d[:x])
@ -187,9 +218,11 @@ function createKWargsList(plt::PlottingObject, x, y; kw...)
d[:linetype] = :path d[:linetype] = :path
end end
# add it to our series list
push!(ret, d) push!(ret, d)
end end
ret
ret, xmeta, ymeta
end end
# pass it off to the x/y version # pass it off to the x/y version
@ -259,8 +292,8 @@ function dataframes!()
end end
# the conversion functions for when we pass symbols or vectors of symbols to reference dataframes # the conversion functions for when we pass symbols or vectors of symbols to reference dataframes
@eval convertToAnyVector(s::Symbol; kw...) = Any[getDataFrameFromKW(;kw...)[s]] @eval convertToAnyVector(s::Symbol; kw...) = Any[getDataFrameFromKW(;kw...)[s]], s
@eval convertToAnyVector(v::AVec{Symbol}; kw...) = (df = getDataFrameFromKW(;kw...); Any[df[s] for s in v]) @eval convertToAnyVector(v::AVec{Symbol}; kw...) = (df = getDataFrameFromKW(;kw...); Any[df[s] for s in v]), v
end end