From 66bd2559b9b51b9698f31a2e928681e203f57cb7 Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Wed, 4 May 2016 16:09:09 -0400 Subject: [PATCH] recipe macro; markershape fix; moved/fixed themes --- src/Plots.jl | 2 ++ src/args.jl | 88 ++++++-------------------------------------------- src/plot.jl | 1 + src/recipes.jl | 19 +++++++++++ src/subplot.jl | 2 ++ src/themes.jl | 65 +++++++++++++++++++++++++++++++++++++ src/utils.jl | 15 ++++++--- 7 files changed, 109 insertions(+), 83 deletions(-) create mode 100644 src/themes.jl diff --git a/src/Plots.jl b/src/Plots.jl index d74f860c..3cabbc8e 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -145,6 +145,7 @@ export chorddiagram, @kw, + @recipe, translate, translate!, @@ -165,6 +166,7 @@ include("colors.jl") include("components.jl") include("backends.jl") include("args.jl") +include("themes.jl") include("plot.jl") include("series_args.jl") include("subplot.jl") diff --git a/src/args.jl b/src/args.jl index bcbe0d00..cd3ba133 100644 --- a/src/args.jl +++ b/src/args.jl @@ -384,84 +384,6 @@ function default(; kw...) end end -# ----------------------------------------------------------------------------- - -const _invisible = RGBA(0,0,0,0) - -const _themes = KW( - :default => KW( - :bg => :white, - :bglegend => :match, - :bginside => :match, - :bgoutside => :match, - :fg => :auto, - :fglegend => :match, - :fggrid => :match, - :fgaxis => :match, - :fgtext => :match, - :fgborder => :match, - :fgguide => :match, - ), - # :ggplot2 => KW( - # :bg => :white, - # :bglegend => _invisible, - # :bginside => :lightgray, - # :bgoutside => :match, - # :fg => :white, - # :fglegend => _invisible, - # :fggrid => :match, - # :fgaxis => :match, - # :fgtext => :gray, - # :fgborder => :match, - # :fgguide => :black, - # ), -) - -function add_theme(sym::Symbol, theme::KW) - _themes[sym] = theme -end - -# add a new theme, using an existing theme as the base -function add_theme(sym::Symbol; - base = :default, # start with this theme - bg = _themes[base][:bg], - bglegend = _themes[base][:bglegend], - bginside = _themes[base][:bginside], - bgoutside = _themes[base][:bgoutside], - fg = _themes[base][:fg], - fglegend = _themes[base][:fglegend], - fggrid = _themes[base][:fggrid], - fgaxis = _themes[base][:fgaxis], - fgtext = _themes[base][:fgtext], - fgborder = _themes[base][:fgborder], - fgguide = _themes[base][:fgguide]) - _themes[sym] = KW( - :bg => bg, - :bglegend => bglegend, - :bginside => bginside, - :bgoutside => bgoutside, - :fg => fg, - :fglegend => fglegend, - :fggrid => fggrid, - :fgaxis => fgaxis, - :fgtext => fgtext, - :fgborder => fgborder, - :fgguide => fgguide, - ) -end - -add_theme(:ggplot2, - bglegend = _invisible, - bginside = :lightgray, - fg = :white, - fglegend = _invisible, - fgtext = :gray, - fgguide = :black -) - -function set_theme(sym::Symbol) - default(; _themes[sym]...) -end # ----------------------------------------------------------------------------- @@ -612,6 +534,14 @@ _replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape) _replace_markershape(shapes::AVec) = map(_replace_markershape, shapes) _replace_markershape(shape) = shape +function _add_markershape(d::KW) + # add the markershape if it needs to be added... hack to allow "m=10" to add a shape, + # and still allow overriding in _apply_recipe + ms = pop!(d, :markershape_to_add, :none) + if !haskey(d, :markershape) && ms != :none + d[:markershape] = ms + end +end "Handle all preprocessing of args... break out colors/sizes/etc and replace aliases." function preprocessArgs!(d::KW) @@ -656,7 +586,7 @@ function preprocessArgs!(d::KW) if haskey(d, :markershape) d[:markershape] = _replace_markershape(d[:markershape]) elseif anymarker - d[:markershape] = :ellipse + d[:markershape_to_add] = :ellipse # add it after _apply_recipe end # handle fill diff --git a/src/plot.jl b/src/plot.jl index 6df93b3f..62bfd14c 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -76,6 +76,7 @@ function plot!(plt::Plot, args...; kw...) # for plotting recipes, swap out the args and update the parameter dictionary args = _apply_recipe(d, args...; kw...) + _add_markershape(d) dumpdict(d, "After plot! preprocessing") warnOnUnsupportedArgs(plt.backend, d) diff --git a/src/recipes.jl b/src/recipes.jl index dafaa0d3..6bc34b1a 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -32,6 +32,25 @@ macro kw(k, v) esc(:(get!(d, $k, $v))) end +macro recipe(args...) + expr = args[end] + for (i,e) in enumerate(expr.args) + if isa(e,Expr) && e.head == :(=>) + k, v = e.args[1:2] + expr.args[i] = :(get!(d, get(Plots._keyAliases, $k, $k), $v)) + end + end + + e = esc(quote + function Plots._apply_recipe(d::KW, $(args[1:end-1]...); kw...) + $expr + end + end) + # @show e + # dump(e,10) + e +end + # macro force_kw(k, v) # esc(:(d[$k] = $v)) # end diff --git a/src/subplot.jl b/src/subplot.jl index 789e732a..f03c7df3 100644 --- a/src/subplot.jl +++ b/src/subplot.jl @@ -44,6 +44,7 @@ function subplot(args...; kw...) # for plotting recipes, swap out the args and update the parameter dictionary args = _apply_recipe(d, args...; kw..., issubplot=true) + _add_markershape(d) # figure out the layout layoutarg = get(d, :layout, nothing) @@ -120,6 +121,7 @@ function _preprocess_subplot(subplt::Subplot, d::KW, args = ()) # for plotting recipes, swap out the args and update the parameter dictionary args = _apply_recipe(d, args...; d..., issubplot=true) + _add_markershape(d) dumpdict(d, "After subplot! preprocessing") diff --git a/src/themes.jl b/src/themes.jl new file mode 100644 index 00000000..e84e2063 --- /dev/null +++ b/src/themes.jl @@ -0,0 +1,65 @@ + +const _invisible = RGBA(0,0,0,0) + +const _themes = KW( + :default => KW( + :bg => :white, + :bglegend => :match, + :bginside => :match, + :bgoutside => :match, + :fg => :auto, + :fglegend => :match, + :fggrid => :match, + :fgaxis => :match, + :fgtext => :match, + :fgborder => :match, + :fgguide => :match, + ) +) + +function add_theme(sym::Symbol, theme::KW) + _themes[sym] = theme +end + +# add a new theme, using an existing theme as the base +function add_theme(sym::Symbol; + base = :default, # start with this theme + bg = _themes[base][:bg], + bglegend = _themes[base][:bglegend], + bginside = _themes[base][:bginside], + bgoutside = _themes[base][:bgoutside], + fg = _themes[base][:fg], + fglegend = _themes[base][:fglegend], + fggrid = _themes[base][:fggrid], + fgaxis = _themes[base][:fgaxis], + fgtext = _themes[base][:fgtext], + fgborder = _themes[base][:fgborder], + fgguide = _themes[base][:fgguide], + kw...) + _themes[sym] = merge(KW( + :bg => bg, + :bglegend => bglegend, + :bginside => bginside, + :bgoutside => bgoutside, + :fg => fg, + :fglegend => fglegend, + :fggrid => fggrid, + :fgaxis => fgaxis, + :fgtext => fgtext, + :fgborder => fgborder, + :fgguide => fgguide, + ), KW(kw)) +end + +add_theme(:ggplot2, + bglegend = _invisible, + bginside = :lightgray, + fg = :white, + fglegend = _invisible, + fgtext = :gray, + fgguide = :black +) + +function set_theme(sym::Symbol) + default(; _themes[sym]...) +end diff --git a/src/utils.jl b/src/utils.jl index 8fd1235e..83f0edb2 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -172,13 +172,20 @@ function replaceType(vec, val) push!(vec, val) end +function replaceAlias!(d::KW, k::Symbol, aliases::KW) + if haskey(aliases, k) + d[aliases[k]] = pop!(d, k) + end +end + function replaceAliases!(d::KW, aliases::KW) ks = collect(keys(d)) for k in ks - if haskey(aliases, k) - d[aliases[k]] = d[k] - delete!(d, k) - end + replaceAlias!(d, k, aliases) + # if haskey(aliases, k) + # d[aliases[k]] = d[k] + # delete!(d, k) + # end end end