pre/post processing subplots

This commit is contained in:
Thomas Breloff 2015-10-21 13:52:58 -04:00
parent ee80ce5ae6
commit 9fcc3cdc24
5 changed files with 324 additions and 929 deletions

File diff suppressed because one or more lines are too long

View File

@ -83,38 +83,38 @@ function createGadflyPlotObject(d::Dict)
Gadfly.Guide.ylabel(d[:ylabel]), Gadfly.Guide.ylabel(d[:ylabel]),
Gadfly.Guide.title(d[:title])] Gadfly.Guide.title(d[:title])]
kwargs = Dict() # kwargs = Dict()
# hide the legend? # # hide the legend?
if !get(d, :legend, true) # if !get(d, :legend, true)
kwargs[:key_position] = :none # kwargs[:key_position] = :none
end # end
if !get(d, :grid, true) # if !get(d, :grid, true)
kwargs[:grid_color] = getColor(d[:background_color]) # kwargs[:grid_color] = getColor(d[:background_color])
end # end
# fonts # # fonts
tfont, gfont, lfont = d[:tickfont], d[:guidefont], d[:legendfont] # tfont, gfont, lfont = d[:tickfont], d[:guidefont], d[:legendfont]
fg = getColor(d[:foreground_color]) # fg = getColor(d[:foreground_color])
gplt.theme = Gadfly.Theme(; # gplt.theme = Gadfly.Theme(;
background_color = getColor(d[:background_color]), # background_color = getColor(d[:background_color]),
minor_label_color = fg, # minor_label_color = fg,
minor_label_font = tfont.family, # minor_label_font = tfont.family,
minor_label_font_size = tfont.pointsize * Gadfly.pt, # minor_label_font_size = tfont.pointsize * Gadfly.pt,
major_label_color = fg, # major_label_color = fg,
major_label_font = gfont.family, # major_label_font = gfont.family,
major_label_font_size = gfont.pointsize * Gadfly.pt, # major_label_font_size = gfont.pointsize * Gadfly.pt,
key_title_color = fg, # key_title_color = fg,
key_title_font = gfont.family, # key_title_font = gfont.family,
key_title_font_size = gfont.pointsize * Gadfly.pt, # key_title_font_size = gfont.pointsize * Gadfly.pt,
key_label_color = fg, # key_label_color = fg,
key_label_font = lfont.family, # key_label_font = lfont.family,
key_label_font_size = lfont.pointsize * Gadfly.pt, # key_label_font_size = lfont.pointsize * Gadfly.pt,
plot_padding = 1 * Gadfly.mm, # plot_padding = 1 * Gadfly.mm,
kwargs... # kwargs...
) # )
gplt gplt
end end
@ -504,6 +504,44 @@ function updateGadflyGuides(plt::Plot, d::Dict)
updateGadflyAxisFlips(gplt, d, xlims, ylims) updateGadflyAxisFlips(gplt, d, xlims, ylims)
end end
function updateGadflyPlotTheme(plt::Plot, d::Dict)
kwargs = Dict()
# get the full initargs, overriding any new settings
# TODO: should this be part of the main `plot` command in plot.jl???
d = merge!(plt.initargs, d)
# hide the legend?
if !get(d, :legend, true)
kwargs[:key_position] = :none
end
if !get(d, :grid, true)
kwargs[:grid_color] = getColor(d[:background_color])
end
# fonts
tfont, gfont, lfont = d[:tickfont], d[:guidefont], d[:legendfont]
fg = getColor(d[:foreground_color])
getGadflyContext(plt).theme = Gadfly.Theme(;
background_color = getColor(d[:background_color]),
minor_label_color = fg,
minor_label_font = tfont.family,
minor_label_font_size = tfont.pointsize * Gadfly.pt,
major_label_color = fg,
major_label_font = gfont.family,
major_label_font_size = gfont.pointsize * Gadfly.pt,
key_title_color = fg,
key_title_font = gfont.family,
key_title_font_size = gfont.pointsize * Gadfly.pt,
key_label_color = fg,
key_label_font = lfont.family,
key_label_font_size = lfont.pointsize * Gadfly.pt,
plot_padding = 1 * Gadfly.mm,
kwargs...
)
end
# ---------------------------------------------------------------- # ----------------------------------------------------------------
@ -558,6 +596,7 @@ end
function updatePlotItems(plt::Plot{GadflyPackage}, d::Dict) function updatePlotItems(plt::Plot{GadflyPackage}, d::Dict)
updateGadflyGuides(plt, d) updateGadflyGuides(plt, d)
updateGadflyPlotTheme(plt, d)
end end

View File

@ -45,6 +45,7 @@ end
function updatePlotItems(plt::Plot{ImmersePackage}, d::Dict) function updatePlotItems(plt::Plot{ImmersePackage}, d::Dict)
updateGadflyGuides(plt, d) updateGadflyGuides(plt, d)
updateGadflyPlotTheme(plt, d)
end end

View File

@ -1,4 +1,10 @@
# TODO: there should be a distinction between an object that will manage a full plot, vs a component of a plot.
# the PlotRecipe as currently implemented is more of a "custom component"
# a recipe should fully describe the plotting command(s) and call them, likewise for updating.
# actually... maybe those should explicitly derive from PlottingObject???
abstract PlotRecipe abstract PlotRecipe
getRecipeXY(recipe::PlotRecipe) = Float64[], Float64[] getRecipeXY(recipe::PlotRecipe) = Float64[], Float64[]

View File

@ -78,6 +78,8 @@ ncols(layout::GridLayout, row::Int) = layout.nc
# get the plot index given row and column # get the plot index given row and column
Base.getindex(layout::GridLayout, r::Int, c::Int) = (r-1) * layout.nc + c Base.getindex(layout::GridLayout, r::Int, c::Int) = (r-1) * layout.nc + c
Base.getindex(subplt::Subplot, args...) = subplt.layout[args...]
# handle "linking" the subplot axes together # handle "linking" the subplot axes together
# each backend should implement the handleLinkInner and expandLimits! methods # each backend should implement the handleLinkInner and expandLimits! methods
function linkAxis(subplt::Subplot, isx::Bool) function linkAxis(subplt::Subplot, isx::Bool)
@ -217,14 +219,68 @@ function subplot{P<:PlottingPackage}(plts::AVec{Plot{P}}, layout::SubplotLayout,
n = sum([plt.n for plt in plts]) n = sum([plt.n for plt in plts])
subplt = Subplot(nothing, collect(plts), P(), p, n, layout, Dict(), false, false, false, (r,c) -> (nothing,nothing)) subplt = Subplot(nothing, collect(plts), P(), p, n, layout, Dict(), false, false, false, (r,c) -> (nothing,nothing))
# update links # # update links
# for s in (:linkx, :linky, :linkfunc)
# if haskey(d, s)
# setfield!(subplt, s, d[s])
# delete!(d, s)
# end
# end
preprocessSubplot(subplt, d)
# # init (after plot creation)
# if !subplt.initialized
# subplt.initialized = buildSubplotObject!(subplt, false)
# end
# # add title, axis labels, ticks, etc
# for (i,plt) in enumerate(subplt.plts)
# di = copy(d)
# for (k,v) in di
# if typeof(v) <: AVec
# di[k] = v[mod1(i, length(v))]
# elseif typeof(v) <: AMat
# m = size(v,2)
# di[k] = (size(v,1) == 1 ? v[1, mod1(i, m)] : v[:, mod1(i, m)])
# end
# end
# dumpdict(di, "Updating sp $i")
# updatePlotItems(plt, di)
# end
# # handle links
# subplt.linkx && linkAxis(subplt, true)
# subplt.linky && linkAxis(subplt, false)
# # set this to be current
# current(subplt)
postprocessSubplot(subplt, d)
subplt
end
# TODO: hcat/vcat subplots and plots together arbitrarily
# ------------------------------------------------------------------------------------------------
function preprocessSubplot(subplt::Subplot, d::Dict)
validateSubplotSupported()
preprocessArgs!(d)
dumpdict(d, "After subplot! preprocessing")
# process links. TODO: extract to separate function
for s in (:linkx, :linky, :linkfunc) for s in (:linkx, :linky, :linkfunc)
if haskey(d, s) if haskey(d, s)
setfield!(subplt, s, d[s]) setfield!(subplt, s, d[s])
delete!(d, s) delete!(d, s)
end end
end end
end
function postprocessSubplot(subplt::Subplot, d::Dict)
# init (after plot creation) # init (after plot creation)
if !subplt.initialized if !subplt.initialized
subplt.initialized = buildSubplotObject!(subplt, false) subplt.initialized = buildSubplotObject!(subplt, false)
@ -251,11 +307,8 @@ function subplot{P<:PlottingPackage}(plts::AVec{Plot{P}}, layout::SubplotLayout,
# set this to be current # set this to be current
current(subplt) current(subplt)
subplt
end end
# TODO: hcat/vcat subplots and plots together arbitrarily
# ------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------
""" """
@ -277,22 +330,20 @@ end
# # this adds to a specific subplot... most plot commands will flow through here # # this adds to a specific subplot... most plot commands will flow through here
function subplot!(subplt::Subplot, args...; kw...) function subplot!(subplt::Subplot, args...; kw...)
validateSubplotSupported() # validateSubplotSupported()
# if !subplotSupported()
# error(CURRENT_BACKEND.sym, " does not support the subplot/subplot! commands at this time. Try one of: ", join(filter(pkg->subplotSupported(backendInstance(pkg)), backends()),", "))
# end
d = Dict(kw) d = Dict(kw)
preprocessArgs!(d) preprocessSubplot(subplt, d)
dumpdict(d, "After subplot! preprocessing") # preprocessArgs!(d)
# dumpdict(d, "After subplot! preprocessing")
# process links. TODO: extract to separate function # # process links. TODO: extract to separate function
for s in (:linkx, :linky, :linkfunc) # for s in (:linkx, :linky, :linkfunc)
if haskey(d, s) # if haskey(d, s)
setfield!(subplt, s, d[s]) # setfield!(subplt, s, d[s])
delete!(d, s) # delete!(d, s)
end # end
end # end
# create the underlying object (each backend will do this differently) # create the underlying object (each backend will do this differently)
# note: we call it once before doing the individual plots, and once after # note: we call it once before doing the individual plots, and once after
@ -333,36 +384,37 @@ function subplot!(subplt::Subplot, args...; kw...)
plot!(plt; di...) plot!(plt; di...)
end end
# -- TODO: extract this section into a separate function... duplicates the other subplot --------- postprocessSubplot(subplt, d)
# # -- TODO: extract this section into a separate function... duplicates the other subplot ---------
# create the underlying object (each backend will do this differently) # # create the underlying object (each backend will do this differently)
if !subplt.initialized # if !subplt.initialized
subplt.initialized = buildSubplotObject!(subplt, false) # subplt.initialized = buildSubplotObject!(subplt, false)
# subplt.initialized = true # # subplt.initialized = true
end # end
# add title, axis labels, ticks, etc # # add title, axis labels, ticks, etc
for (i,plt) in enumerate(subplt.plts) # for (i,plt) in enumerate(subplt.plts)
di = copy(d) # di = copy(d)
for (k,v) in di # for (k,v) in di
if typeof(v) <: AVec # if typeof(v) <: AVec
di[k] = v[mod1(i, length(v))] # di[k] = v[mod1(i, length(v))]
elseif typeof(v) <: AMat # elseif typeof(v) <: AMat
m = size(v,2) # m = size(v,2)
di[k] = (size(v,1) == 1 ? v[1, mod1(i, m)] : v[:, mod1(i, m)]) # di[k] = (size(v,1) == 1 ? v[1, mod1(i, m)] : v[:, mod1(i, m)])
end # end
end # end
dumpdict(di, "Updating sp $i") # dumpdict(di, "Updating sp $i")
updatePlotItems(plt, di) # updatePlotItems(plt, di)
end # end
subplt.linkx && linkAxis(subplt, true) # subplt.linkx && linkAxis(subplt, true)
subplt.linky && linkAxis(subplt, false) # subplt.linky && linkAxis(subplt, false)
# set this to be current # # set this to be current
current(subplt) # current(subplt)
# --- end extract ---- # # --- end extract ----
# show it automatically? # show it automatically?
if haskey(d, :show) && d[:show] if haskey(d, :show) && d[:show]