axis link arg; change those subplot/axis args set in kwlist to apply just to its own subplot; markerstrokealpha matches markeralpha

This commit is contained in:
Thomas Breloff 2016-06-14 00:10:26 -04:00
parent 0e598cc51d
commit b5b4023056
6 changed files with 90 additions and 99 deletions

View File

@ -239,6 +239,7 @@ const _axis_defaults = KW(
:scale => :identity, :scale => :identity,
:rotation => 0, :rotation => 0,
:flip => false, :flip => false,
:link => [],
:tickfont => font(8), :tickfont => font(8),
:guidefont => font(11), :guidefont => font(11),
:foreground_color_axis => :match, # axis border/tick colors, :foreground_color_axis => :match, # axis border/tick colors,
@ -272,6 +273,7 @@ for letter in (:x,:y,:z)
:scale, :scale,
:rotation, :rotation,
:flip, :flip,
:link,
:tickfont, :tickfont,
:guidefont, :guidefont,
:foreground_color_axis, :foreground_color_axis,
@ -401,8 +403,6 @@ add_aliases(:size, :windowsize, :wsize)
add_aliases(:window_title, :windowtitle, :wtitle) add_aliases(:window_title, :windowtitle, :wtitle)
add_aliases(:show, :gui, :display) add_aliases(:show, :gui, :display)
add_aliases(:color_palette, :palette) add_aliases(:color_palette, :palette)
# add_aliases(:linkx, :xlink)
# add_aliases(:linky, :ylink)
add_aliases(:overwrite_figure, :clf, :clearfig, :overwrite, :reuse) add_aliases(:overwrite_figure, :clf, :clearfig, :overwrite, :reuse)
add_aliases(:xerror, :xerr, :xerrorbar) add_aliases(:xerror, :xerr, :xerrorbar)
add_aliases(:yerror, :yerr, :yerrorbar, :err, :errorbar) 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) color_or_nothing!(sp.attr, :background_color_subplot)
bg = convertColor(sp[:background_color_subplot]) bg = convertColor(sp[:background_color_subplot])
sp.attr[:color_palette] = get_color_palette(sp.attr[:color_palette], bg, 30) 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_nothing!(sp.attr, :background_color_legend)
# color_or_match!(sp.attr, :background_color_inside, bg)
color_or_nothing!(sp.attr, :background_color_inside) color_or_nothing!(sp.attr, :background_color_inside)
# foreground colors # 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_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_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_nothing!(sp.attr, :foreground_color_grid)
# color_or_match!(sp.attr, :foreground_color_title, fg)
color_or_nothing!(sp.attr, :foreground_color_title) color_or_nothing!(sp.attr, :foreground_color_title)
# for k in (:left_margin, :top_margin, :right_margin, :bottom_margin) # 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) for letter in (:x, :y, :z)
# get (maybe initialize) the axis # get (maybe initialize) the axis
axissym = Symbol(letter, :axis) axis = get_axis(sp, letter)
axis = if haskey(sp.attr, axissym)
sp.attr[axissym]
else
sp.attr[axissym] = Axis(sp, letter)
end
# grab magic args (for example `xaxis = (:flip, :log)`) # 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) # build the KW of arguments from the letter version (i.e. xticks --> ticks)
kw = KW() kw = KW()
# DD(d_in, "d_in before")
for (k,v) in _axis_defaults for (k,v) in _axis_defaults
# first get the args without the letter: `tickfont = font(10)` # 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) # 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"` # then get those args that were passed with a leading letter: `xlabel = "X"`
lk = Symbol(letter, k) lk = Symbol(letter, k)
if haskey(d_in, lk) if haskey(d_in, lk)
# kw[k] = slice_arg(pop!(d_in, lk), subplot_index)
kw[k] = slice_arg(d_in[lk], subplot_index) kw[k] = slice_arg(d_in[lk], subplot_index)
end end
end end
@ -1009,23 +995,28 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::I
# update the axis # update the axis
update!(axis, args...; kw...) update!(axis, args...; kw...)
# # update the axis colors # convert a bool into auto or nothing
# color_or_match!(axis.d, :foreground_color_axis, fg) if isa(axis[:ticks], Bool)
color_or_nothing!(axis.d, :foreground_color_axis) axis[:ticks] = axis[:ticks] ? :auto : nothing
# 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?
end end
# # now we can get rid of the axis keys without a letter # # update the axis colors
# for k in keys(_axis_defaults) color_or_nothing!(axis.d, :foreground_color_axis)
# delete!(d_in, k) color_or_nothing!(axis.d, :foreground_color_border)
# end color_or_nothing!(axis.d, :foreground_color_guide)
color_or_nothing!(axis.d, :foreground_color_text)
# 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
end end

View File

@ -32,6 +32,15 @@ function Axis(sp::Subplot, letter::Symbol, args...; kw...)
update!(Axis(sp, d), args...; kw...) update!(Axis(sp, d), args...; kw...)
end 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 = "") function process_axis_arg!(d::KW, arg, letter = "")
T = typeof(arg) T = typeof(arg)
arg = get(_scaleAliases, arg, arg) arg = get(_scaleAliases, arg, arg)

View File

@ -19,9 +19,9 @@ function _create_backend_figure(plt::Plot{[PkgName]Backend})
nothing nothing
end end
# this is called early in the pipeline, use it to make the plot current or something # # this is called early in the pipeline, use it to make the plot current or something
function _prepare_plot_object(plt::Plot{[PkgName]Backend}) # function _prepare_plot_object(plt::Plot{[PkgName]Backend})
end # end
# Set up the subplot within the backend object. # Set up the subplot within the backend object.
function _initialize_subplot(plt::Plot{[PkgName]Backend}, sp::Subplot{[PkgName]Backend}) function _initialize_subplot(plt::Plot{[PkgName]Backend}, sp::Subplot{[PkgName]Backend})

View File

@ -5,7 +5,7 @@
const px = AbsoluteLength(0.254) const px = AbsoluteLength(0.254)
const pct = Length{:pct, Float64}(1.0) 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 const _cbar_width = 5mm
@ -556,44 +556,13 @@ rowsize(v) = isrow(v) ? length(v.args) : 1
function create_grid(expr::Expr) function create_grid(expr::Expr)
# cellsym = gensym(:cell)
# @show expr
if iscol(expr) if iscol(expr)
create_grid_vcat(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) elseif isrow(expr)
:(let cell = GridLayout(1, $(length(expr.args))) :(let cell = GridLayout(1, $(length(expr.args)))
$([:(cell[1,$i] = $(create_grid(v))) for (i,v) in enumerate(expr.args)]...) $([:(cell[1,$i] = $(create_grid(v))) for (i,v) in enumerate(expr.args)]...)
cell cell
end) 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 elseif expr.head == :curly
create_grid_curly(expr) create_grid_curly(expr)
@ -606,17 +575,14 @@ end
function create_grid_vcat(expr::Expr) function create_grid_vcat(expr::Expr)
rowsizes = map(rowsize, expr.args) rowsizes = map(rowsize, expr.args)
rmin, rmax = extrema(rowsizes) rmin, rmax = extrema(rowsizes)
# @show rmin, rmax
if rmin > 0 && rmin == rmax if rmin > 0 && rmin == rmax
# we have a grid... build the whole thing # we have a grid... build the whole thing
# note: rmin is the number of columns # note: rmin is the number of columns
nr = length(expr.args) nr = length(expr.args)
nc = rmin nc = rmin
# @show nr, nc
body = Expr(:block) body = Expr(:block)
for r=1:nr for r=1:nr
arg = expr.args[r] arg = expr.args[r]
# @show r, arg
if isrow(arg) if isrow(arg)
for (c,item) in enumerate(arg.args) for (c,item) in enumerate(arg.args)
push!(body.args, :(cell[$r,$c] = $(create_grid(item)))) 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)))) push!(body.args, :(cell[$r,1] = $(create_grid(arg))))
end end
end end
# @show body
:(let cell = GridLayout($nr, $nc) :(let cell = GridLayout($nr, $nc)
$body $body
cell cell
end) 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 else
# otherwise just build one row at a time # otherwise just build one row at a time
:(let cell = GridLayout($(length(expr.args)), 1) :(let cell = GridLayout($(length(expr.args)), 1)
$([:(cell[$i,1] = $(create_grid(v))) for (i,v) in enumerate(expr.args)]...) $([:(cell[$i,1] = $(create_grid(v))) for (i,v) in enumerate(expr.args)]...)
cell cell
end) 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
end end

View File

@ -105,8 +105,8 @@ function plot(plt1::Plot, plts_tail::Plot...; kw...)
end end
end end
# 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)
_prepare_plot_object(plt) # _prepare_plot_object(plt)
# first apply any args for the subplots # first apply any args for the subplots
for (idx,sp) in enumerate(plt.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 # merge in anything meant for plot/subplot/axis
for kw in kw_list for kw in kw_list
for (k,v) in kw for (k,v) in kw
for defdict in (_plot_defaults, for defdict in (_plot_defaults,)
_subplot_defaults, # _subplot_defaults,
_axis_defaults, # _axis_defaults,
_axis_defaults_byletter) # _axis_defaults_byletter)
if haskey(defdict, k) if haskey(defdict, k)
d[k] = pop!(kw, k) d[k] = pop!(kw, k)
end end
@ -345,6 +345,7 @@ function _plot!(plt::Plot, d::KW, args...)
_update_plot_args(plt, d) _update_plot_args(plt, d)
if !plt.init if !plt.init
plt.o = _create_backend_figure(plt) plt.o = _create_backend_figure(plt)
# DD(d)
# create the layout and subplots from the inputs # create the layout and subplots from the inputs
plt.layout, plt.subplots, plt.spmap = build_layout(plt.attr) plt.layout, plt.subplots, plt.spmap = build_layout(plt.attr)
@ -379,14 +380,48 @@ function _plot!(plt::Plot, d::KW, args...)
end end
end end
# just in case the backend needs to set up the plot (make it current or something) # we'll keep a map of subplot to an attribute override dict.
_prepare_plot_object(plt) # 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 # first apply any args for the subplots
for (idx,sp) in enumerate(plt.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 end
# do we need to link any axes together? # do we need to link any axes together?
link_axes!(plt.layout, plt[:link]) link_axes!(plt.layout, plt[:link])
@ -398,14 +433,15 @@ function _plot!(plt::Plot, d::KW, args...)
for (i,kw) in enumerate(kw_list) for (i,kw) in enumerate(kw_list)
command_idx = kw[:series_plotindex] - kw_list[1][:series_plotindex] + 1 command_idx = kw[:series_plotindex] - kw_list[1][:series_plotindex] + 1
# get the Subplot object to which the series belongs # # get the Subplot object to which the series belongs
sp = get(kw, :subplot, :auto) # sp = get(kw, :subplot, :auto)
sp = if sp == :auto # sp = if sp == :auto
mod1(i,length(plt.subplots)) # mod1(i,length(plt.subplots))
else # else
slice_arg(sp, i) # slice_arg(sp, i)
end # end
sp = kw[:subplot] = get_subplot(plt, sp) # sp = kw[:subplot] = get_subplot(plt, sp)
sp = kw[:subplot]
idx = get_subplot_index(plt, sp) idx = get_subplot_index(plt, sp)
# strip out series annotations (those which are based on series x/y coords) # strip out series annotations (those which are based on series x/y coords)

View File

@ -46,11 +46,14 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
d[:markerstrokecolor] = c d[:markerstrokecolor] = c
# update alphas # update alphas
for asym in (:linealpha, :markeralpha, :markerstrokealpha, :fillalpha) for asym in (:linealpha, :markeralpha, :fillalpha)
if d[asym] == nothing if d[asym] == nothing
d[asym] = d[:seriesalpha] d[asym] = d[:seriesalpha]
end end
end end
if d[:markerstrokealpha] == nothing
d[:markerstrokealpha] = d[:markeralpha]
end
# scatter plots don't have a line, but must have a shape # scatter plots don't have a line, but must have a shape
if d[:seriestype] in (:scatter, :scatter3d) if d[:seriestype] in (:scatter, :scatter3d)