From b5b40230565dc84eef29a9d797605dd664b0afc8 Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Tue, 14 Jun 2016 00:10:26 -0400 Subject: [PATCH] axis link arg; change those subplot/axis args set in kwlist to apply just to its own subplot; markerstrokealpha matches markeralpha --- src/args.jl | 47 +++++++++++--------------- src/axes.jl | 9 +++++ src/backends/template.jl | 6 ++-- src/layouts.jl | 50 +--------------------------- src/plot.jl | 72 ++++++++++++++++++++++++++++++---------- src/series_new.jl | 5 ++- 6 files changed, 90 insertions(+), 99 deletions(-) diff --git a/src/args.jl b/src/args.jl index 628f435c..495232be 100644 --- a/src/args.jl +++ b/src/args.jl @@ -239,6 +239,7 @@ const _axis_defaults = KW( :scale => :identity, :rotation => 0, :flip => false, + :link => [], :tickfont => font(8), :guidefont => font(11), :foreground_color_axis => :match, # axis border/tick colors, @@ -272,6 +273,7 @@ for letter in (:x,:y,:z) :scale, :rotation, :flip, + :link, :tickfont, :guidefont, :foreground_color_axis, @@ -401,8 +403,6 @@ add_aliases(:size, :windowsize, :wsize) add_aliases(:window_title, :windowtitle, :wtitle) add_aliases(:show, :gui, :display) add_aliases(:color_palette, :palette) -# add_aliases(:linkx, :xlink) -# add_aliases(:linky, :ylink) add_aliases(:overwrite_figure, :clf, :clearfig, :overwrite, :reuse) add_aliases(:xerror, :xerr, :xerrorbar) add_aliases(:yerror, :yerr, :yerrorbar, :err, :errorbar) @@ -954,19 +954,13 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::I color_or_nothing!(sp.attr, :background_color_subplot) bg = convertColor(sp[:background_color_subplot]) sp.attr[:color_palette] = get_color_palette(sp.attr[:color_palette], bg, 30) - # color_or_match!(sp.attr, :background_color_legend, bg) color_or_nothing!(sp.attr, :background_color_legend) - # color_or_match!(sp.attr, :background_color_inside, bg) color_or_nothing!(sp.attr, :background_color_inside) # foreground colors - # fg = color_or_match!(sp.attr, :foreground_color_subplot, plt.attr[:foreground_color]) color_or_nothing!(sp.attr, :foreground_color_subplot) - # color_or_match!(sp.attr, :foreground_color_legend, fg) color_or_nothing!(sp.attr, :foreground_color_legend) - # color_or_match!(sp.attr, :foreground_color_grid, fg) color_or_nothing!(sp.attr, :foreground_color_grid) - # color_or_match!(sp.attr, :foreground_color_title, fg) color_or_nothing!(sp.attr, :foreground_color_title) # for k in (:left_margin, :top_margin, :right_margin, :bottom_margin) @@ -977,20 +971,13 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::I for letter in (:x, :y, :z) # get (maybe initialize) the axis - axissym = Symbol(letter, :axis) - axis = if haskey(sp.attr, axissym) - sp.attr[axissym] - else - sp.attr[axissym] = Axis(sp, letter) - end + axis = get_axis(sp, letter) # grab magic args (for example `xaxis = (:flip, :log)`) - args = wraptuple(get(d_in, axissym, ())) + args = wraptuple(get(d_in, Symbol(letter, :axis), ())) # build the KW of arguments from the letter version (i.e. xticks --> ticks) kw = KW() - # DD(d_in, "d_in before") - for (k,v) in _axis_defaults # first get the args without the letter: `tickfont = font(10)` # note: we don't pop because we want this to apply to all axes! (delete after all have finished) @@ -1001,7 +988,6 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::I # then get those args that were passed with a leading letter: `xlabel = "X"` lk = Symbol(letter, k) if haskey(d_in, lk) - # kw[k] = slice_arg(pop!(d_in, lk), subplot_index) kw[k] = slice_arg(d_in[lk], subplot_index) end end @@ -1009,23 +995,28 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::I # update the axis update!(axis, args...; kw...) + # convert a bool into auto or nothing + if isa(axis[:ticks], Bool) + axis[:ticks] = axis[:ticks] ? :auto : nothing + end + # # update the axis colors - # color_or_match!(axis.d, :foreground_color_axis, fg) color_or_nothing!(axis.d, :foreground_color_axis) - # color_or_match!(axis.d, :foreground_color_border, fg) color_or_nothing!(axis.d, :foreground_color_border) - # color_or_match!(axis.d, :foreground_color_guide, fg) color_or_nothing!(axis.d, :foreground_color_guide) - # color_or_match!(axis.d, :foreground_color_text, fg) color_or_nothing!(axis.d, :foreground_color_text) - # TODO: need to handle linking here? + # handle linking here. if we're passed a list of + # other subplots to link to, link them together + link = axis[:link] + if !isempty(link) + for other_sp in link + other_sp = get_subplot(plt, other_sp) + link_axes!(axis, get_axis(other_sp, letter)) + end + axis.d[:link] = [] + end end - - # # now we can get rid of the axis keys without a letter - # for k in keys(_axis_defaults) - # delete!(d_in, k) - # end end diff --git a/src/axes.jl b/src/axes.jl index a2e409b8..d8bfe3c2 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -32,6 +32,15 @@ function Axis(sp::Subplot, letter::Symbol, args...; kw...) update!(Axis(sp, d), args...; kw...) end +function get_axis(sp::Subplot, letter::Symbol) + axissym = Symbol(letter, :axis) + if haskey(sp.attr, axissym) + sp.attr[axissym] + else + sp.attr[axissym] = Axis(sp, letter) + end +end + function process_axis_arg!(d::KW, arg, letter = "") T = typeof(arg) arg = get(_scaleAliases, arg, arg) diff --git a/src/backends/template.jl b/src/backends/template.jl index 3d0efdc1..82b009ab 100644 --- a/src/backends/template.jl +++ b/src/backends/template.jl @@ -19,9 +19,9 @@ function _create_backend_figure(plt::Plot{[PkgName]Backend}) nothing end -# this is called early in the pipeline, use it to make the plot current or something -function _prepare_plot_object(plt::Plot{[PkgName]Backend}) -end +# # this is called early in the pipeline, use it to make the plot current or something +# function _prepare_plot_object(plt::Plot{[PkgName]Backend}) +# end # Set up the subplot within the backend object. function _initialize_subplot(plt::Plot{[PkgName]Backend}, sp::Subplot{[PkgName]Backend}) diff --git a/src/layouts.jl b/src/layouts.jl index cc1590be..9440da31 100644 --- a/src/layouts.jl +++ b/src/layouts.jl @@ -5,7 +5,7 @@ const px = AbsoluteLength(0.254) const pct = Length{:pct, Float64}(1.0) -to_pixels(m::AbsoluteLength) = m / 0.254 +to_pixels(m::AbsoluteLength) = m.value / 0.254 const _cbar_width = 5mm @@ -556,44 +556,13 @@ rowsize(v) = isrow(v) ? length(v.args) : 1 function create_grid(expr::Expr) - # cellsym = gensym(:cell) - # @show expr if iscol(expr) create_grid_vcat(expr) - # rowsizes = map(rowsize, expr.args) - # rmin, rmax = extrema(rowsizes) - # if rmin > 0 && rmin == rmax - # # we have a grid... build the whole thing - # # note: rmin is the number of columns - # nr = length(expr.args) - # nc = rmin - # - # :(let cell = GridLayout($nr, $nc) - # $([:(cell[$r,$c] = $(create_grid(expr.args[r], c))) for r=1:nr, c=1:nc]...) - # for r=1:nr - # layout = $(create_grid(expr.args[r]) - # cell[r,] - # $([:($cellsym[$r,1] = $(create_grid(expr.args[r]))) for r=1:length(expr.args)]...) - # $cellsym - # end) - # else - # # otherwise just build one row at a time - # :(let - # $cellsym = GridLayout($(length(expr.args)), 1) - # $([:($cellsym[$i,1] = $(create_grid(expr.args[i]))) for i=1:length(expr.args)]...) - # $cellsym - # end) - # end elseif isrow(expr) :(let cell = GridLayout(1, $(length(expr.args))) $([:(cell[1,$i] = $(create_grid(v))) for (i,v) in enumerate(expr.args)]...) cell end) - # :(let - # $cellsym = GridLayout(1, $(length(expr.args))) - # $([:($cellsym[1,$i] = $(create_grid(expr.args[i]))) for i=1:length(expr.args)]...) - # $cellsym - # end) elseif expr.head == :curly create_grid_curly(expr) @@ -606,17 +575,14 @@ end function create_grid_vcat(expr::Expr) rowsizes = map(rowsize, expr.args) rmin, rmax = extrema(rowsizes) - # @show rmin, rmax if rmin > 0 && rmin == rmax # we have a grid... build the whole thing # note: rmin is the number of columns nr = length(expr.args) nc = rmin - # @show nr, nc body = Expr(:block) for r=1:nr arg = expr.args[r] - # @show r, arg if isrow(arg) for (c,item) in enumerate(arg.args) push!(body.args, :(cell[$r,$c] = $(create_grid(item)))) @@ -625,30 +591,16 @@ function create_grid_vcat(expr::Expr) push!(body.args, :(cell[$r,1] = $(create_grid(arg)))) end end - # @show body :(let cell = GridLayout($nr, $nc) $body cell end) - # :(let cell = GridLayout($nr, $nc) - # $([:(cell[$r,$c] = $(create_grid(expr.args[r], c))) for r=1:nr, c=1:nc]...) - # for r=1:nr - # layout = $(create_grid(expr.args[r]) - # cell[r,] - # $([:($cellsym[$r,1] = $(create_grid(expr.args[r]))) for r=1:length(expr.args)]...) - # $cellsym - # end) else # otherwise just build one row at a time :(let cell = GridLayout($(length(expr.args)), 1) $([:(cell[$i,1] = $(create_grid(v))) for (i,v) in enumerate(expr.args)]...) cell end) - # :(let - # $cellsym = GridLayout($(length(expr.args)), 1) - # $([:($cellsym[$i,1] = $(create_grid(expr.args[i]))) for i=1:length(expr.args)]...) - # $cellsym - # end) end end diff --git a/src/plot.jl b/src/plot.jl index 52181c75..3de99120 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -105,8 +105,8 @@ function plot(plt1::Plot, plts_tail::Plot...; kw...) end end - # just in case the backend needs to set up the plot (make it current or something) - _prepare_plot_object(plt) + # # just in case the backend needs to set up the plot (make it current or something) + # _prepare_plot_object(plt) # first apply any args for the subplots for (idx,sp) in enumerate(plt.subplots) @@ -330,10 +330,10 @@ function _plot!(plt::Plot, d::KW, args...) # merge in anything meant for plot/subplot/axis for kw in kw_list for (k,v) in kw - for defdict in (_plot_defaults, - _subplot_defaults, - _axis_defaults, - _axis_defaults_byletter) + for defdict in (_plot_defaults,) + # _subplot_defaults, + # _axis_defaults, + # _axis_defaults_byletter) if haskey(defdict, k) d[k] = pop!(kw, k) end @@ -345,6 +345,7 @@ function _plot!(plt::Plot, d::KW, args...) _update_plot_args(plt, d) if !plt.init plt.o = _create_backend_figure(plt) + # DD(d) # create the layout and subplots from the inputs plt.layout, plt.subplots, plt.spmap = build_layout(plt.attr) @@ -355,7 +356,7 @@ function _plot!(plt::Plot, d::KW, args...) plt.init = true end - + # handle inset subplots insets = plt[:inset_subplots] @@ -379,14 +380,48 @@ function _plot!(plt::Plot, d::KW, args...) end end - # just in case the backend needs to set up the plot (make it current or something) - _prepare_plot_object(plt) + # we'll keep a map of subplot to an attribute override dict. + # any series which belong to that subplot + sp_attrs = Dict{Subplot,Any}() + for (i,kw) in enumerate(kw_list) + # get the Subplot object to which the series belongs + sp = get(kw, :subplot, :auto) + sp = if sp == :auto + mod1(i,length(plt.subplots)) + else + slice_arg(sp, i) + end + sp = kw[:subplot] = get_subplot(plt, sp) + # idx = get_subplot_index(plt, sp) + attr = KW() + + for (k,v) in kw + for defdict in (_subplot_defaults, + _axis_defaults, + _axis_defaults_byletter) + if haskey(defdict, k) + attr[k] = pop!(kw, k) + end + end + end + sp_attrs[sp] = attr + end + + + + # # just in case the backend needs to set up the plot (make it current or something) + # _prepare_plot_object(plt) # first apply any args for the subplots for (idx,sp) in enumerate(plt.subplots) - _update_subplot_args(plt, sp, d, idx, remove_pair = false) + # if we picked up any subplot-specific overrides, merge them here + attr = merge(d, get(sp_attrs, sp, KW())) + # DD(attr, "sp$idx") + _update_subplot_args(plt, sp, attr, idx, remove_pair = false) end + + # do we need to link any axes together? link_axes!(plt.layout, plt[:link]) @@ -398,14 +433,15 @@ function _plot!(plt::Plot, d::KW, args...) for (i,kw) in enumerate(kw_list) command_idx = kw[:series_plotindex] - kw_list[1][:series_plotindex] + 1 - # get the Subplot object to which the series belongs - sp = get(kw, :subplot, :auto) - sp = if sp == :auto - mod1(i,length(plt.subplots)) - else - slice_arg(sp, i) - end - sp = kw[:subplot] = get_subplot(plt, sp) + # # get the Subplot object to which the series belongs + # sp = get(kw, :subplot, :auto) + # sp = if sp == :auto + # mod1(i,length(plt.subplots)) + # else + # slice_arg(sp, i) + # end + # sp = kw[:subplot] = get_subplot(plt, sp) + sp = kw[:subplot] idx = get_subplot_index(plt, sp) # strip out series annotations (those which are based on series x/y coords) diff --git a/src/series_new.jl b/src/series_new.jl index fc3c224c..c4cddc0c 100644 --- a/src/series_new.jl +++ b/src/series_new.jl @@ -46,11 +46,14 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) d[:markerstrokecolor] = c # update alphas - for asym in (:linealpha, :markeralpha, :markerstrokealpha, :fillalpha) + for asym in (:linealpha, :markeralpha, :fillalpha) if d[asym] == nothing d[asym] = d[:seriesalpha] end end + if d[:markerstrokealpha] == nothing + d[:markerstrokealpha] = d[:markeralpha] + end # scatter plots don't have a line, but must have a shape if d[:seriestype] in (:scatter, :scatter3d)