From 6049a9fa0a0ceecb0b8ba7d4f3758e1c78ec702d Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Thu, 12 May 2016 12:31:47 -0400 Subject: [PATCH] working on recipes overhaul --- src/Plots.jl | 2 +- src/args.jl | 178 +++++++++++++++++++++++----------------------- src/plot.jl | 8 ++- src/recipes.jl | 90 +++++++++++------------ src/series_new.jl | 93 ++++++++++++++++++++++++ 5 files changed, 234 insertions(+), 137 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 665cb0d6..e62f513e 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -280,7 +280,7 @@ yaxis!(plt::Plot, args...; kw...) = plot!(pl const CURRENT_BACKEND = CurrentBackend(:none) -setup_dataframes() +# setup_dataframes() function __init__() setup_ijulia() diff --git a/src/args.jl b/src/args.jl index 1f26f418..65ebe192 100644 --- a/src/args.jl +++ b/src/args.jl @@ -806,92 +806,92 @@ end function has_black_border_for_default(lt::Symbol) like_histogram(lt) || lt in (:hexbin, :bar) end - -# build the argument dictionary for a series -function getSeriesArgs(pkg::AbstractBackend, plotargs::KW, kw, commandIndex::Int, plotIndex::Int, globalIndex::Int) # TODO, pass in plotargs, not plt - kwdict = KW(kw) - d = KW() - - # add defaults? - for k in keys(_seriesDefaults) - setDictValue(kwdict, d, k, commandIndex, _seriesDefaults) - end - - # groupby args? - for k in (:idxfilter, :numUncounted, :dataframe) - if haskey(kwdict, k) - d[k] = kwdict[k] - end - end - - if haskey(_typeAliases, d[:linetype]) - d[:linetype] = _typeAliases[d[:linetype]] - end - - aliasesAndAutopick(d, :axis, _axesAliases, supportedAxes(pkg), plotIndex) - aliasesAndAutopick(d, :linestyle, _styleAliases, supportedStyles(pkg), plotIndex) - aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex) - - # update color - d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], plotargs, plotIndex) - - # # update linecolor - # c = d[:linecolor] - # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex)) - # d[:linecolor] = c - - # # update markercolor - # c = d[:markercolor] - # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex)) - # d[:markercolor] = c - - # # update fillcolor - # c = d[:fillcolor] - # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex)) - # d[:fillcolor] = c - - # update colors - for csym in (:linecolor, :markercolor, :fillcolor) - d[csym] = if d[csym] == :match - if has_black_border_for_default(d[:linetype]) && csym == :linecolor - :black - else - d[:seriescolor] - end - else - getSeriesRGBColor(d[csym], plotargs, plotIndex) - end - end - - # update markerstrokecolor - c = d[:markerstrokecolor] - c = (c == :match ? plotargs[:foreground_color] : getSeriesRGBColor(c, plotargs, plotIndex)) - d[:markerstrokecolor] = c - - # update alphas - for asym in (:linealpha, :markeralpha, :markerstrokealpha, :fillalpha) - if d[asym] == nothing - d[asym] = d[:seriesalpha] - end - end - - # scatter plots don't have a line, but must have a shape - if d[:linetype] in (:scatter, :scatter3d) - d[:linewidth] = 0 - if d[:markershape] == :none - d[:markershape] = :ellipse - end - end - - # set label - label = d[:label] - label = (label == "AUTO" ? "y$globalIndex" : label) - if d[:axis] == :right && !(length(label) >= 4 && label[end-3:end] != " (R)") - label = string(label, " (R)") - end - d[:label] = label - - warnOnUnsupported(pkg, d) - - d -end +# +# # build the argument dictionary for a series +# function getSeriesArgs(pkg::AbstractBackend, plotargs::KW, kw, commandIndex::Int, plotIndex::Int, globalIndex::Int) # TODO, pass in plotargs, not plt +# kwdict = KW(kw) +# d = KW() +# +# # add defaults? +# for k in keys(_seriesDefaults) +# setDictValue(kwdict, d, k, commandIndex, _seriesDefaults) +# end +# +# # groupby args? +# for k in (:idxfilter, :numUncounted, :dataframe) +# if haskey(kwdict, k) +# d[k] = kwdict[k] +# end +# end +# +# if haskey(_typeAliases, d[:linetype]) +# d[:linetype] = _typeAliases[d[:linetype]] +# end +# +# aliasesAndAutopick(d, :axis, _axesAliases, supportedAxes(pkg), plotIndex) +# aliasesAndAutopick(d, :linestyle, _styleAliases, supportedStyles(pkg), plotIndex) +# aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex) +# +# # update color +# d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], plotargs, plotIndex) +# +# # # update linecolor +# # c = d[:linecolor] +# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex)) +# # d[:linecolor] = c +# +# # # update markercolor +# # c = d[:markercolor] +# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex)) +# # d[:markercolor] = c +# +# # # update fillcolor +# # c = d[:fillcolor] +# # c = (c == :match ? d[:seriescolor] : getSeriesRGBColor(c, plotargs, plotIndex)) +# # d[:fillcolor] = c +# +# # update colors +# for csym in (:linecolor, :markercolor, :fillcolor) +# d[csym] = if d[csym] == :match +# if has_black_border_for_default(d[:linetype]) && csym == :linecolor +# :black +# else +# d[:seriescolor] +# end +# else +# getSeriesRGBColor(d[csym], plotargs, plotIndex) +# end +# end +# +# # update markerstrokecolor +# c = d[:markerstrokecolor] +# c = (c == :match ? plotargs[:foreground_color] : getSeriesRGBColor(c, plotargs, plotIndex)) +# d[:markerstrokecolor] = c +# +# # update alphas +# for asym in (:linealpha, :markeralpha, :markerstrokealpha, :fillalpha) +# if d[asym] == nothing +# d[asym] = d[:seriesalpha] +# end +# end +# +# # scatter plots don't have a line, but must have a shape +# if d[:linetype] in (:scatter, :scatter3d) +# d[:linewidth] = 0 +# if d[:markershape] == :none +# d[:markershape] = :ellipse +# end +# end +# +# # set label +# label = d[:label] +# label = (label == "AUTO" ? "y$globalIndex" : label) +# if d[:axis] == :right && !(length(label) >= 4 && label[end-3:end] != " (R)") +# label = string(label, " (R)") +# end +# d[:label] = label +# +# warnOnUnsupported(pkg, d) +# +# d +# end diff --git a/src/plot.jl b/src/plot.jl index 50553e0d..a82d0f57 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -96,7 +96,7 @@ function _plot!(plt::Plot, d::KW, args...) # finished (no more args) get added to the kw_list, and the rest go into the queue # for processing. kw_list = KW[] - still_to_process = [RecipesBase.Series(copy(d), args)] + still_to_process = [RecipeData(copy(d), args)] while !isempty(still_to_process) next_series = pop!(still_to_process) series_list = RecipesBase.apply_recipe(next_series.d, next_series.args...) @@ -143,7 +143,8 @@ function _plot!(plt::Plot, d::KW, args...) # _add_series(plt, d, args...) # this is it folks! - for kw in kw_list + # TODO: we probably shouldn't use i for tracking series index, but rather explicitly track it in recipes + for (i,kw) in enumerate(kw_list) plt.n += 1 # TODO: can this be handled as a recipe?? @@ -166,6 +167,9 @@ function _plot!(plt::Plot, d::KW, args...) # merge!(plt.plotargs, plotarg_overrides) # end + _add_defaults!(kw, plt, i) + # getSeriesArgs(plt.backend, getplotargs(plt, n), d, commandIndex, convertSeriesIndex(plt, n), n) + _replace_linewidth(kw) _add_series(plt.backend, plt, kw) end diff --git a/src/recipes.jl b/src/recipes.jl index cd290435..b3376b1f 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -29,51 +29,51 @@ function RecipesBase.apply_recipe(d::KW, kw::KW, args...; issubplot=false) end -if is_installed("DataFrames") - @eval begin - import DataFrames - DFS = Union{Symbol, AbstractArray{Symbol}} - - function handle_dfs(df::DataFrames.AbstractDataFrame, d::KW, letter, dfs::DFS) - if isa(dfs, Symbol) - get!(d, symbol(letter * "label"), string(dfs)) - collect(df[dfs]) - else - get!(d, :label, reshape(dfs, 1, length(dfs))) - Any[collect(df[s]) for s in dfs] - end - end - - function handle_group(df::DataFrames.AbstractDataFrame, d::KW) - if haskey(d, :group) - g = d[:group] - if isa(g, Symbol) - d[:group] = collect(df[g]) - end - end - end - - @recipe function f(df::DataFrames.AbstractDataFrame, sy::DFS) - handle_group(df, d) - handle_dfs(df, d, "y", sy) - end - - @recipe function f(df::DataFrames.AbstractDataFrame, sx::DFS, sy::DFS) - handle_group(df, d) - x = handle_dfs(df, d, "x", sx) - y = handle_dfs(df, d, "y", sy) - x, y - end - - @recipe function f(df::DataFrames.AbstractDataFrame, sx::DFS, sy::DFS, sz::DFS) - handle_group(df, d) - x = handle_dfs(df, d, "x", sx) - y = handle_dfs(df, d, "y", sy) - z = handle_dfs(df, d, "z", sz) - x, y, z - end - end -end +# if is_installed("DataFrames") +# @eval begin +# import DataFrames +# DFS = Union{Symbol, AbstractArray{Symbol}} +# +# function handle_dfs(df::DataFrames.AbstractDataFrame, d::KW, letter, dfs::DFS) +# if isa(dfs, Symbol) +# get!(d, symbol(letter * "label"), string(dfs)) +# collect(df[dfs]) +# else +# get!(d, :label, reshape(dfs, 1, length(dfs))) +# Any[collect(df[s]) for s in dfs] +# end +# end +# +# function handle_group(df::DataFrames.AbstractDataFrame, d::KW) +# if haskey(d, :group) +# g = d[:group] +# if isa(g, Symbol) +# d[:group] = collect(df[g]) +# end +# end +# end +# +# @recipe function f(df::DataFrames.AbstractDataFrame, sy::DFS) +# handle_group(df, d) +# handle_dfs(df, d, "y", sy) +# end +# +# @recipe function f(df::DataFrames.AbstractDataFrame, sx::DFS, sy::DFS) +# handle_group(df, d) +# x = handle_dfs(df, d, "x", sx) +# y = handle_dfs(df, d, "y", sy) +# x, y +# end +# +# @recipe function f(df::DataFrames.AbstractDataFrame, sx::DFS, sy::DFS, sz::DFS) +# handle_group(df, d) +# x = handle_dfs(df, d, "x", sx) +# y = handle_dfs(df, d, "y", sy) +# z = handle_dfs(df, d, "z", sz) +# x, y, z +# end +# end +# end # macro kw(k, v) # esc(:(get!(d, $k, $v))) diff --git a/src/series_new.jl b/src/series_new.jl index 2836e498..09de7649 100644 --- a/src/series_new.jl +++ b/src/series_new.jl @@ -1,10 +1,103 @@ # we are going to build recipes to do the processing and splitting of the args + +# build the argument dictionary for a series +# function getSeriesArgs(pkg::AbstractBackend, plotargs::KW, d, commandIndex::Int, plotIndex::Int, globalIndex::Int) # TODO, pass in plotargs, not plt +function _add_defaults!(d::KW, plt::Plot, commandIndex::Int) + # kwdict = KW(d) + # d = KW() + pkg = plt.backend + n = plt.n + plotargs = getplotargs(plt, n) + plotIndex = convertSeriesIndex(plt, n) + globalIndex = n + + # add defaults? + for k in keys(_seriesDefaults) + setDictValue(d, d, k, commandIndex, _seriesDefaults) + end + + # # groupby args? + # for k in (:idxfilter, :numUncounted, :dataframe) + # if haskey(kwdict, k) + # d[k] = kwdict[k] + # end + # end + + if haskey(_typeAliases, d[:linetype]) + d[:linetype] = _typeAliases[d[:linetype]] + end + + aliasesAndAutopick(d, :axis, _axesAliases, supportedAxes(pkg), plotIndex) + aliasesAndAutopick(d, :linestyle, _styleAliases, supportedStyles(pkg), plotIndex) + aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex) + + # update color + d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], plotargs, plotIndex) + + # update colors + for csym in (:linecolor, :markercolor, :fillcolor) + d[csym] = if d[csym] == :match + if has_black_border_for_default(d[:linetype]) && csym == :linecolor + :black + else + d[:seriescolor] + end + else + getSeriesRGBColor(d[csym], plotargs, plotIndex) + end + end + + # update markerstrokecolor + c = d[:markerstrokecolor] + c = (c == :match ? plotargs[:foreground_color] : getSeriesRGBColor(c, plotargs, plotIndex)) + d[:markerstrokecolor] = c + + # update alphas + for asym in (:linealpha, :markeralpha, :markerstrokealpha, :fillalpha) + if d[asym] == nothing + d[asym] = d[:seriesalpha] + end + end + + # scatter plots don't have a line, but must have a shape + if d[:linetype] in (:scatter, :scatter3d) + d[:linewidth] = 0 + if d[:markershape] == :none + d[:markershape] = :ellipse + end + end + + # set label + label = d[:label] + label = (label == "AUTO" ? "y$globalIndex" : label) + if d[:axis] == :right && !(length(label) >= 4 && label[end-3:end] != " (R)") + label = string(label, " (R)") + end + d[:label] = label + + warnOnUnsupported(pkg, d) + + d +end + +# ------------------------------------------------------------------- +# ------------------------------------------------------------------- + # instead of process_inputs: + +@recipe function f{Y<:Number}(y::AVec{Y}) + x --> 1:length(y) + y --> y + dumpdict(d,"y",true) + () +end + @recipe function f{X<:Number,Y<:Number}(x::AVec{X}, y::AVec{Y}) x --> x y --> y + dumpdict(d,"xy",true) () end