working on subplot/axis arg processing

This commit is contained in:
Thomas Breloff 2016-05-18 14:08:44 -04:00
parent df7fc0c4df
commit 327f235af9
19 changed files with 240 additions and 93 deletions

View File

@ -292,6 +292,7 @@ function __init__()
setup_ijulia()
# setup_dataframes()
setup_atom()
# add_axis_letter_defaults()
end
# ---------------------------------------------------------

View File

@ -170,15 +170,15 @@ _plot_defaults[:size] = (600,400)
_plot_defaults[:pos] = (0,0)
_plot_defaults[:windowtitle] = "Plots.jl"
_plot_defaults[:show] = false
_plot_defaults[:layout] = :auto
_plot_defaults[:num_subplots] = -1
_plot_defaults[:num_rows] = -1
_plot_defaults[:num_cols] = -1
_plot_defaults[:layout] = 1
# _plot_defaults[:num_subplots] = -1
# _plot_defaults[:num_rows] = -1
# _plot_defaults[:num_cols] = -1
_plot_defaults[:link] = false
_plot_defaults[:linkx] = false
_plot_defaults[:linky] = false
_plot_defaults[:linkfunc] = nothing
_plot_defaults[:overwrite_figure] = false
_plot_defaults[:overwrite_figure] = true
const _subplot_defaults = KW()
@ -196,12 +196,13 @@ _subplot_defaults[:colorbar] = :legend
_subplot_defaults[:legendfont] = font(8)
_subplot_defaults[:grid] = true
_subplot_defaults[:annotation] = nothing # annotation tuple(s)... (x,y,annotation)
_subplot_defaults[:polar] = false
# _subplot_defaults[:polar] = false
_subplot_defaults[:projection] = :none # can also be :polar or :3d
_subplot_defaults[:aspect_ratio] = :none # choose from :none or :equal
const _axis_defaults = KW()
_axis_defaults[:label] = ""
_axis_defaults[:guide] = ""
_axis_defaults[:lims] = :auto
_axis_defaults[:ticks] = :auto
_axis_defaults[:scale] = :identity
@ -214,11 +215,36 @@ _axis_defaults[:foreground_color_border] = :match # plot area border/
_axis_defaults[:foreground_color_text] = :match # tick text color
_axis_defaults[:foreground_color_guide] = :match # guide text color
# add defaults for the letter versions
const _axis_defaults_byletter = KW()
for letter in (:x,:y,:z)
for k in (:guide,
:lims,
:ticks,
:scale,
:rotation,
:flip,
:tickfont,
:guidefont,
:foreground_color_axis,
:foreground_color_border,
:foreground_color_text,
:foreground_color_guide)
_axis_defaults_byletter[symbol(letter,k)] = nothing
end
end
@show _axis_defaults
# for letter in (:x, :y, :z)
# for (k,v) in _axis_defaults
# _axis_defaults[symbol(letter,k)] = v
# end
# end
const _all_defaults = KW[
_series_defaults,
_plot_defaults,
_subplot_defaults,
_axis_defaults
_axis_defaults_byletter
]
const _all_args = sort(collect(union(map(keys, _all_defaults)...)))
@ -315,18 +341,18 @@ add_aliases(:group, :g, :grouping)
add_aliases(:bins, :bin, :nbin, :nbins, :nb)
add_aliases(:ribbon, :rib)
add_aliases(:annotation, :ann, :anns, :annotate, :annotations)
add_aliases(:xlabel, :xlab, :xl)
add_aliases(:xguide, :xlabel, :xlab, :xl)
add_aliases(:xlims, :xlim, :xlimit, :xlimits)
add_aliases(:xticks, :xtick)
add_aliases(:xrotation, :xrot, :xr)
add_aliases(:ylabel, :ylab, :yl)
add_aliases(:xguide, :ylabel, :ylab, :yl)
add_aliases(:ylims, :ylim, :ylimit, :ylimits)
add_aliases(:yticks, :ytick)
add_aliases(:yrightlabel, :yrlab, :yrl, :ylabel2, :y2label, :ylab2, :y2lab, :ylabr, :ylabelright)
add_aliases(:yrightlims, :yrlim, :yrlimit, :yrlimits)
add_aliases(:yrightticks, :yrtick)
# add_aliases(:yrightlabel, :yrlab, :yrl, :ylabel2, :y2label, :ylab2, :y2lab, :ylabr, :ylabelright)
# add_aliases(:yrightlims, :yrlim, :yrlimit, :yrlimits)
# add_aliases(:yrightticks, :yrtick)
add_aliases(:yrotation, :yrot, :yr)
add_aliases(:zlabel, :zlab, :zl)
add_aliases(:zguide, :zlabel, :zlab, :zl)
add_aliases(:zlims, :zlim, :zlimit, :zlimits)
add_aliases(:zticks, :ztick)
add_aliases(:zrotation, :zrot, :zr)
@ -340,9 +366,9 @@ add_aliases(:show, :gui, :display)
add_aliases(:color_palette, :palette)
add_aliases(:linkx, :xlink)
add_aliases(:linky, :ylink)
add_aliases(:num_subplots, :n, :numplots, :nplts)
add_aliases(:num_rows, :nr, :nrow, :nrows, :rows)
add_aliases(:num_cols, :nc, :ncol, :ncols, :cols, :ncolumns, :columns)
# add_aliases(:num_subplots, :n, :numplots, :nplts)
# add_aliases(:num_rows, :nr, :nrow, :nrows, :rows)
# add_aliases(:num_cols, :nc, :ncol, :ncols, :cols, :ncolumns, :columns)
add_aliases(:overwrite_figure, :clf, :clearfig, :overwrite, :reuse)
add_aliases(:xerror, :xerr, :xerrorbar)
add_aliases(:yerror, :yerr, :yerrorbar, :err, :errorbar)
@ -351,6 +377,7 @@ add_aliases(:normalize, :norm, :normed, :normalized)
add_aliases(:aspect_ratio, :aspectratio, :axis_ratio, :axisratio, :ratio)
add_aliases(:match_dimensions, :transpose, :transpose_z)
add_aliases(:subplot, :sp, :subplt, :splt)
add_aliases(:projection, :proj)
# add all pluralized forms to the _keyAliases dict
@ -839,13 +866,16 @@ slice_arg(v, idx) = v
# given an argument key (k), we want to extract the argument value for this index.
# matrices are sliced by column, otherwise we
# if nothing is set (or container is empty), return the default or the existing value.
function slice_arg!(d_in::KW, d_out::KW, k::Symbol, default_value, idx::Int = 1)
v = pop!(d_in, k, get(d_out, k, default_value))
d_out[k] = if haskey(d_in, k) && typeof(v) <: AMat && !isempty(v)
function slice_arg!(d_in::KW, d_out::KW, k::Symbol, default_value, idx::Int = 1; new_key::Symbol = k, remove_pair::Bool = true)
v = get(d_in, k, get(d_out, new_key, default_value))
d_out[new_key] = if haskey(d_in, k) && typeof(v) <: AMat && !isempty(v)
slice_arg(v, idx)
else
v
end
if remove_pair
delete!(d_in, k)
end
end
# if the value is `:match` then we take whatever match_color is.
@ -882,11 +912,12 @@ end
# update a subplots args and axes
function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW)
function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW, subplot_index::Integer)
pargs = plt.plotargs
spargs = sp.subplotargs
# @show subplot_index, sp
for (k,v) in _subplot_defaults
slice_arg!(d_in, spargs, k, v)
slice_arg!(d_in, spargs, k, v, subplot_index)
end
# handle legend/colorbar
@ -907,6 +938,9 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW)
color_or_match!(spargs, :foreground_color_legend, fg)
color_or_match!(spargs, :foreground_color_grid, fg)
# info("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
# DD(spargs, "before loop")
for letter in (:x, :y, :z)
# get (maybe initialize) the axis
axissym = symbol(letter, :axis)
@ -917,14 +951,38 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW)
# build the KW of arguments from the letter version (i.e. xticks --> ticks)
kw = KW()
for k in _axis_defaults
# 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)
if haskey(d_in, k)
kw[k] = slice_arg(d_in[k], subplot_index)
end
# then get those args that were passed with a leading letter: `xlabel = "X"`
lk = symbol(letter, k)
if haskey(d_in, lk)
kw[k] = d_in[lk]
kw[k] = slice_arg(pop!(d_in, lk), subplot_index)
end
end
# for (k,v) in _axis_defaults
# # first get the args without the letter: `tickfont = font(10)`
# slice_arg!(d_in, kw, k, v, subplot_index)
#
# # then get those args that were passed with a leading letter: `xlabel = "X"`
# lk = symbol(letter, k)
# slice_arg!(d_in, kw, lk, v, subplot_index; new_key = k)
# # if haskey(d_in, lk)
# # kw[k] = d_in[lk]
# # end
# end
# DD(d_in, "d_in after")
# DD(kw, "kw")
# update the axis
# @show args,kw
update!(axis, args...; kw...)
# update the axis colors
@ -932,7 +990,16 @@ function _update_subplot_args(plt::Plot, sp::Subplot, d_in::KW)
color_or_match!(axis.d, :foreground_color_border, fg)
color_or_match!(axis.d, :foreground_color_guide, fg)
color_or_match!(axis.d, :foreground_color_text, fg)
# DD(axis.d, "axis")
end
# now we can get rid of the axis keys without a letter
for k in keys(_axis_defaults)
delete!(d_in, k)
end
# DD(spargs[:xaxis].d, "after loop")
# info("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
end

View File

@ -39,11 +39,11 @@ supportedArgs(::BokehBackend) = [
:title,
# :windowtitle,
:x,
# :xlabel,
# :xguide,
# :xlims,
# :xticks,
:y,
# :ylabel,
# :yguide,
# :ylims,
# :yrightlabel,
# :yticks,

View File

@ -13,9 +13,9 @@ supportedArgs(::GadflyBackend) = [
:fillrange, :fillcolor, :fillalpha,
:bins, :n, :nc, :nr, :layout, :smooth,
:title, :windowtitle, :show, :size,
:x, :xlabel, :xlims, :xticks, :xscale, :xflip,
:y, :ylabel, :ylims, :yticks, :yscale, :yflip,
# :z, :zlabel, :zlims, :zticks, :zscale, :zflip,
:x, :xguide, :xlims, :xticks, :xscale, :xflip,
:y, :yguide, :ylims, :yticks, :yscale, :yflip,
# :z, :zguide, :zlims, :zticks, :zscale, :zflip,
:z,
:tickfont, :guidefont, :legendfont,
:grid, :legend, :colorbar,
@ -59,8 +59,8 @@ function createGadflyPlotObject(d::KW)
gplt.data_source = Gadfly.DataFrames.DataFrame()
# gplt.layers = gplt.layers[1:0]
gplt.layers = [Gadfly.layer(Gadfly.Geom.point(tag=:remove), x=zeros(1), y=zeros(1));] # x=MissingVec(), y=MissingVec());]
gplt.guides = Gadfly.GuideElement[Gadfly.Guide.xlabel(d[:xlabel]),
Gadfly.Guide.ylabel(d[:ylabel]),
gplt.guides = Gadfly.GuideElement[Gadfly.Guide.xlabel(d[:xguide]),
Gadfly.Guide.ylabel(d[:yguide]),
Gadfly.Guide.title(d[:title])]
gplt
end
@ -469,8 +469,8 @@ end
function updateGadflyGuides(plt::Plot, d::KW)
gplt = getGadflyContext(plt)
haskey(d, :title) && findGuideAndSet(gplt, Gadfly.Guide.title, string(d[:title]))
haskey(d, :xlabel) && findGuideAndSet(gplt, Gadfly.Guide.xlabel, string(d[:xlabel]))
haskey(d, :ylabel) && findGuideAndSet(gplt, Gadfly.Guide.ylabel, string(d[:ylabel]))
haskey(d, :xguide) && findGuideAndSet(gplt, Gadfly.Guide.xlabel, string(d[:xguide]))
haskey(d, :yguide) && findGuideAndSet(gplt, Gadfly.Guide.ylabel, string(d[:yguide]))
xlims, xfunc = addGadflyLimitsScale(gplt, d, true)
ylims, yfunc = addGadflyLimitsScale(gplt, d, false)

View File

@ -39,11 +39,11 @@ supportedArgs(::GLVisualizeBackend) = [
# :title,
# :windowtitle,
# :x,
# :xlabel,
# :xguide,
# :xlims,
# :xticks,
# :y,
# :ylabel,
# :yguide,
# :ylims,
# :yrightlabel,
# :yticks,

View File

@ -20,10 +20,10 @@ supportedArgs(::GRBackend) = [
:n, :nc, :nr, :layout,
:smooth,
:title, :windowtitle, :show, :size,
:x, :xlabel, :xlims, :xticks, :xscale, :xflip,
:y, :ylabel, :ylims, :yticks, :yscale, :yflip,
:x, :xguide, :xlims, :xticks, :xscale, :xflip,
:y, :yguide, :ylims, :yticks, :yscale, :yflip,
# :axis, :yrightlabel,
:z, :zlabel, :zlims, :zticks, :zscale, :zflip,
:z, :zguide, :zlims, :zticks, :zscale, :zflip,
:z,
:tickfont, :guidefont, :legendfont,
:grid, :legend, :colorbar,
@ -409,19 +409,19 @@ function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
GR.text(0.5 * (viewport[1] + viewport[2]), vp[4], d[:title])
GR.restorestate()
end
if get(d, :xlabel, "") != ""
if get(d, :xguide, "") != ""
GR.savestate()
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_BOTTOM)
GR.settextcolorind(fg)
GR.text(0.5 * (viewport[1] + viewport[2]), vp[3], d[:xlabel])
GR.text(0.5 * (viewport[1] + viewport[2]), vp[3], d[:xguide])
GR.restorestate()
end
if get(d, :ylabel, "") != ""
if get(d, :yguide, "") != ""
GR.savestate()
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
GR.setcharup(-1, 0)
GR.settextcolorind(fg)
GR.text(vp[1], 0.5 * (viewport[3] + viewport[4]), d[:ylabel])
GR.text(vp[1], 0.5 * (viewport[3] + viewport[4]), d[:yguide])
GR.restorestate()
end
# if get(d, :yrightlabel, "") != ""
@ -872,7 +872,7 @@ end
# end
function _update_plot(plt::Plot{GRBackend}, d::KW)
for k in (:title, :xlabel, :ylabel)
for k in (:title, :xguide, :yguide)
haskey(d, k) && (plt.plotargs[k] = d[k])
end
end

View File

@ -38,11 +38,11 @@ supportedArgs(::PGFPlotsBackend) = [
:title,
# :windowtitle,
:x,
:xlabel,
:xguide,
:xlims,
# :xticks,
:y,
:ylabel,
:yguide,
:ylims,
# :yrightlabel,
# :yticks,
@ -297,7 +297,7 @@ end
function _pgfplots_get_axis_kwargs(d)
axisargs = KW()
for arg in (:xlabel, :ylabel, :zlabel, :title)
for arg in (:xguide, :yguide, :zguide, :title)
axisargs[arg] = d[arg]
end
axisargs[:style] = ""

View File

@ -19,9 +19,9 @@ supportedArgs(::PlotlyBackend) = [
:n, :nc, :nr, :layout,
# :smooth,
:title, :windowtitle, :show, :size,
:x, :xlabel, :xlims, :xticks, :xscale, :xflip, :xrotation,
:y, :ylabel, :ylims, :yticks, :yscale, :yflip, :yrotation,
:z, :zlabel, :zlims, :zticks, :zscale, :zflip, :zrotation,
:x, :xguide, :xlims, :xticks, :xscale, :xflip, :xrotation,
:y, :yguide, :ylims, :yticks, :yscale, :yflip, :yrotation,
:z, :zguide, :zlims, :zticks, :zscale, :zflip, :zrotation,
:z,
:tickfont, :guidefont, :legendfont,
:grid, :legend, :colorbar,

View File

@ -38,11 +38,11 @@ supportedArgs(::PlotlyJSBackend) = [
:title,
:windowtitle,
:x,
:xlabel,
:xguide,
:xlims,
:xticks,
:y,
:ylabel,
:yguide,
:ylims,
# :yrightlabel,
:yticks,

View File

@ -20,10 +20,10 @@ supportedArgs(::PyPlotBackend) = [
:n, :nc, :nr, :layout,
:smooth,
:title, :windowtitle, :show, :size,
:x, :xlabel, :xlims, :xticks, :xscale, :xflip, :xrotation,
:y, :ylabel, :ylims, :yticks, :yscale, :yflip, :yrotation,
:x, :xguide, :xlims, :xticks, :xscale, :xflip, :xrotation,
:y, :yguide, :ylims, :yticks, :yscale, :yflip, :yrotation,
# :axis, :yrightlabel,
:z, :zlabel, :zlims, :zticks, :zscale, :zflip, :zrotation,
:z, :zguide, :zlims, :zticks, :zscale, :zflip, :zrotation,
:z,
:tickfont, :guidefont, :legendfont,
:grid, :legend, :colorbar,
@ -383,7 +383,14 @@ end
function _initialize_subplot(plt::Plot{PyPlotBackend}, sp::Subplot{PyPlotBackend})
fig = plt.o
# add a new axis, and force it to create a new one by setting a distinct label
ax = fig[:add_axes]([0,0,1,1], label = string(gensym()))
proj = sp.subplotargs[:projection]
ax = fig[:add_axes](
[0,0,1,1],
label = string(gensym()),
projection = (proj in (nothing,:none) ? nothing : string(proj))
)
# projection =
# ax = fig[:add_subplot](111, projection = _py_projections[sp.subplotargs[:projection]])
# for axis in (:xaxis, :yaxis)
# ax[axis][:_autolabelpos] = false
# end
@ -1130,11 +1137,13 @@ function _update_plot(plt::Plot{PyPlotBackend}, d::KW)
axissym = symbol(letter, :axis)
axis = spargs[axissym]
# @show axis
# DD(axis.d, "updateplot")
# @show haskey(ax, axissym)
haskey(ax, axissym) || continue
applyPyPlotScale(ax, axis[:scale], letter)
addPyPlotLims(ax, axis[:lims], letter)
addPyPlotTicks(ax, get_ticks(axis), letter)
ax[symbol("set_", letter, "label")](axis[:label])
ax[symbol("set_", letter, "label")](axis[:guide])
if get(axis.d, :flip, false)
ax[symbol("invert_", letter, "axis")]()
end

View File

@ -33,11 +33,11 @@ supportedArgs(::QwtBackend) = [
:title,
:windowtitle,
:x,
:xlabel,
:xguide,
:xlims,
:xticks,
:y,
:ylabel,
:yguide,
:ylims,
:yrightlabel,
:yticks,
@ -192,8 +192,8 @@ end
function _update_plot(plt::Plot{QwtBackend}, d::KW)
haskey(d, :title) && Qwt.title(plt.o, d[:title])
haskey(d, :xlabel) && Qwt.xlabel(plt.o, d[:xlabel])
haskey(d, :ylabel) && Qwt.ylabel(plt.o, d[:ylabel])
haskey(d, :xguide) && Qwt.xlabel(plt.o, d[:xguide])
haskey(d, :yguide) && Qwt.ylabel(plt.o, d[:yguide])
updateLimsAndTicks(plt, d, true)
updateLimsAndTicks(plt, d, false)
end

View File

@ -37,11 +37,11 @@ supportedArgs(::UnicodePlotsBackend) = [
:title,
:windowtitle,
:x,
:xlabel,
:xguide,
:xlims,
# :xticks,
:y,
:ylabel,
:yguide,
:ylims,
# :yrightlabel,
# :yticks,
@ -116,8 +116,8 @@ function rebuildUnicodePlot!(plt::Plot)
ylim = ylim)
# set the axis labels
UnicodePlots.xlabel!(o, iargs[:xlabel])
UnicodePlots.ylabel!(o, iargs[:ylabel])
UnicodePlots.xlabel!(o, iargs[:xguide])
UnicodePlots.ylabel!(o, iargs[:yguide])
# now use the ! functions to add to the plot
for d in sargs
@ -209,7 +209,7 @@ end
function _update_plot(plt::Plot{UnicodePlotsBackend}, d::KW)
for k in (:title, :xlabel, :ylabel, :xlims, :ylims)
for k in (:title, :xguide, :yguide, :xlims, :ylims)
if haskey(d, k)
plt.plotargs[k] = d[k]
end

View File

@ -41,11 +41,11 @@ supportedArgs(::WinstonBackend) = [
:title,
:windowtitle,
:x,
:xlabel,
:xguide,
:xlims,
# :xticks,
:y,
:ylabel,
:yguide,
:ylims,
# :yrightlabel,
# :yticks,
@ -105,8 +105,8 @@ end
function _create_backend_figure(plt::Plot{WinstonBackend})
Winston.FramedPlot(
title = plt.plotargs[:title],
xlabel = plt.plotargs[:xlabel],
ylabel = plt.plotargs[:ylabel]
xlabel = plt.plotargs[:xguide],
ylabel = plt.plotargs[:yguide]
)
end
@ -229,7 +229,7 @@ end
function _update_plot(plt::Plot{WinstonBackend}, d::KW)
window, canvas, wplt = getWinstonItems(plt)
for k in (:xlabel, :ylabel, :title, :xlims, :ylims)
for k in (:xguide, :yguide, :title, :xlims, :ylims)
if haskey(d, k)
Winston.setattr(wplt, string(get(_winstonNames, k, k)), d[k])
end

View File

@ -333,9 +333,9 @@ function update!(a::Axis, args...; kw...)
# then override for any keywords... only those keywords that already exists in d
for (k,v) in kw
sym = symbol(string(k)[2:end])
if haskey(d, sym)
d[sym] = v
# sym = symbol(string(k)[2:end])
if haskey(d, k)
d[k] = v
end
end
a

View File

@ -286,8 +286,8 @@ function _add_series_subplot(subplt::Subplot, d::KW, ::Void, args...;
# cleanup the dictionary that we pass into the plot! command
di[:show] = false
di[:subplot] = true
for k in (:title, :xlabel, :xticks, :xlims, :xscale, :xflip,
:ylabel, :yticks, :ylims, :yscale, :yflip)
for k in (:title, :xguide, :xticks, :xlims, :xscale, :xflip,
:yguide, :yticks, :ylims, :yscale, :yflip)
delete!(di, k)
end
dumpdict(di, "subplot! kwList $i")

View File

@ -46,19 +46,25 @@ function plot(args...; kw...)
pkg = backend()
d = KW(kw)
preprocessArgs!(d)
DD(d,"pre")
# create an empty Plot, update the args using the inputs, then pass it
# to the backend to finish backend-specific initialization
plt = Plot()
_update_plot_args(plt, d)
DD(plt.plotargs,"pargs")
plt.o = _create_backend_figure(plt)
# create the layout and subplots from the inputs
plt.layout, plt.subplots, plt.spmap = build_layout(plt.plotargs)
for sp in plt.subplots
for (idx,sp) in enumerate(plt.subplots)
# update the subplot/axis args from inputs, then pass to backend to init further
sp.plt = plt
_update_subplot_args(plt, sp, d)
_update_subplot_args(plt, sp, copy(d), idx)
DD(sp.subplotargs[:xaxis].d,"$idx")
# TODO: i'd like to know what projection we're using by this point... can I push this off until later??
# I won't easily be able to auto-determine what series types are coming...
_initialize_subplot(plt, sp)
end
@ -155,7 +161,8 @@ function _apply_series_recipe(plt::Plot, d::KW)
# getting ready to add the series... last update to subplot from anything
# that might have been added during series recipes
sp = d[:subplot]
_update_subplot_args(plt, sp, d)
sp_idx = get_subplot_index(plt, sp)
_update_subplot_args(plt, sp, d, sp_idx)
# adjust extrema and discrete info
for s in (:x, :y, :z)
@ -202,8 +209,8 @@ function _plot!(plt::Plot, d::KW, args...)
_before_add_series(plt)
# first apply any args for the subplots
for sp in plt.subplots
_update_subplot_args(plt, sp, d)
for (idx,sp) in enumerate(plt.subplots)
_update_subplot_args(plt, sp, d, idx)
end
# the grouping mechanism is a recipe on a GroupBy object
@ -317,6 +324,7 @@ function _plot!(plt::Plot, d::KW, args...)
# this is it folks!
# 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)
# DD(kw, "series $i before")
if !(get(kw, :seriestype, :none) in (:xerror, :yerror))
plt.n += 1
end
@ -327,12 +335,17 @@ function _plot!(plt::Plot, d::KW, args...)
sp = 1 # TODO: something useful
end
sp = kw[:subplot] = get_subplot(plt, sp)
idx = get_subplot_index(plt, sp)
# we update subplot args in case something like the color palatte is part of the recipe
_update_subplot_args(plt, sp, kw)
# DD(sp.subplotargs[:xaxis].d, "before USA $i")
# DD(kw, "kw")
_update_subplot_args(plt, sp, kw, idx)
# DD(sp.subplotargs[:xaxis].d, "after USA $i")
# set default values, select from attribute cycles, and generally set the final attributes
_add_defaults!(kw, plt, sp, i)
# DD(kw, "series $i after")
#
@ -342,7 +355,9 @@ function _plot!(plt::Plot, d::KW, args...)
# For example, a histogram is just a bar plot with binned data, a bar plot is really a filled step plot,
# and a step plot is really just a path. So any backend that supports drawing a path will implicitly
# be able to support step, bar, and histogram plots (and any recipes that use those components).
# DD(sp.subplotargs[:xaxis].d, "before $i")
_apply_series_recipe(plt, kw)
# DD(sp.subplotargs[:xaxis].d, "after $i")
end
# now that we're done adding all the series, add the annotations
@ -501,7 +516,7 @@ end
# TODO: remove
# # should we update the x/y label given the meta info during input slicing?
# function updateDictWithMeta(d::KW, plotargs::KW, meta::Symbol, isx::Bool)
# lsym = isx ? :xlabel : :ylabel
# lsym = isx ? :xguide : :yguide
# if plotargs[lsym] == default(lsym)
# d[lsym] = string(meta)
# end

View File

@ -13,12 +13,14 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int)
# for k in keys(_series_defaults)
# setDictValue(d, d, k, commandIndex, _series_defaults)
# end
# add default values to our dictionary, being careful not to delete what we just added!
for (k,v) in _series_defaults
slice_arg!(d, d, k, v, commandIndex)
slice_arg!(d, d, k, v, commandIndex, remove_pair = false)
end
# this is how many series belong to this subplot
plotIndex = count(series -> series.d[:subplot] === sp, plt.series_list)
plotIndex = count(series -> series.d[:subplot] === sp, plt.series_list) + 1
# aliasesAndAutopick(d, :axis, _axesAliases, supportedAxes(pkg), plotIndex)
aliasesAndAutopick(d, :linestyle, _styleAliases, supportedStyles(pkg), plotIndex)

View File

@ -3,6 +3,8 @@
# ----------------------------------------------------------------------
Base.show(io::IO, layout::AbstractLayout) = print(io, "$(typeof(layout))$(size(layout))")
# this is the available area for drawing everything in this layout... as percentages of total canvas
bbox(layout::AbstractLayout) = layout.bbox
bbox!(layout::AbstractLayout, bb::BoundingBox) = (layout.bbox = bb)
@ -235,17 +237,62 @@ end
# ----------------------------------------------------------------------
# return the top-level layout, a list of subplots, and a SubplotMap
# # build_layout should return a tuple: (a top-level layout, a list of subplots, and a SubplotMap)
# function build_layout(d::KW)
# layout = get(d, :layout, default(:layout))
# T = typeof(layout)
# if T <: AbstractLayout
# build_layout(layout)
# elseif T <: Integer
# if layout == 1
# # just a single subplot
# sp = Subplot(backend())
# sp, Subplot[sp], SubplotMap((1,1) => sp)
# else
# nr, nc = compute_gridsize(layout)
# build_layout(GridLayout(nr, nc), layout)
# end
# elseif T <: NTuple{2}
# build_layout(GridLayout(layout...))
# elseif T <: NTuple{3}
# n, nr, nc = layout
# build_layout(GridLayout())
# else
# error("unhandled layout type $T: $layout")
# end
# end
# pass the layout arg through
function build_layout(d::KW)
l = get(d, :layout, :auto)
n = get(d, :num_subplots, -1)
nr = get(d, :num_rows, -1)
nc = get(d, :num_cols, -1)
build_layout(get(d, :layout, default(:layout)))
end
l == :auto || error() # TODO: handle anything else
function build_layout(n::Integer)
nr, nc = compute_gridsize(n, -1, -1)
build_layout(GridLayout(nr, nc), n)
end
function build_layout{I<:Integer}(sztup::NTuple{2,I})
nr, nc = sztup
build_layout(GridLayout(nr, nc))
end
function build_layout{I<:Integer}(sztup::NTuple{3,I})
n, nr, nc = sztup
nr, nc = compute_gridsize(n, nr, nc)
layout = GridLayout(nr, nc)
build_layout(GridLayout(nr, nc), n)
end
# compute number of subplots
function build_layout(layout::GridLayout)
nr, nc = size(layout)
build_layout(layout, nr*nc)
end
# n is the number of subplots
function build_layout(layout::GridLayout, n::Integer)
nr, nc = size(layout)
subplots = Subplot[]
spmap = SubplotMap()
i = 1
@ -260,12 +307,14 @@ function build_layout(d::KW)
layout, subplots, spmap
end
build_layout(huh) = error("unhandled layout type $(typeof(huh)): $huh")
# ----------------------------------------------------------------------
function compute_gridsize(numplts::Int, nr::Int, nc::Int)
# figure out how many rows/columns we need
if nr == -1
if nc == -1
if nr < 1
if nc < 1
nr = round(Int, sqrt(numplts))
nc = ceil(Int, numplts / nr)
else
@ -284,6 +333,9 @@ get_subplot(plt::Plot, i::Integer) = plt.subplots[i]
get_subplot(plt::Plot, k) = plt.spmap[k]
get_subplot(series::Series) = series.d[:subplot]
get_subplot_index(plt::Plot, idx::Integer) = idx
get_subplot_index(plt::Plot, sp::Subplot) = findfirst(sp->sp === plt.subplots[2], plt.subplots)
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------

View File

@ -440,6 +440,7 @@ function dumpdict(d::KW, prefix = "", alwaysshow = false)
end
println()
end
DD(d::KW, prefix = "") = dumpdict(d, prefix, true)
function dumpcallstack()