cleanup and fixes for subplot logic

This commit is contained in:
Thomas Breloff 2015-10-24 20:59:42 -04:00
parent e76ded69e6
commit e08957f5ec
5 changed files with 27 additions and 117 deletions

View File

@ -638,9 +638,7 @@ function getSeriesArgs(pkg::PlottingPackage, initargs::Dict, kw, commandIndex::I
aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex) aliasesAndAutopick(d, :markershape, _markerAliases, supportedMarkers(pkg), plotIndex)
# update color # update color
# dumpdict(d, "before color")
d[:color] = getSeriesRGBColor(d[:color], initargs, plotIndex) d[:color] = getSeriesRGBColor(d[:color], initargs, plotIndex)
# dumpdict(d, "after color")
# update markercolor # update markercolor
mc = d[:markercolor] mc = d[:markercolor]

View File

@ -121,7 +121,7 @@ nop() = nothing
makePyPlotCurrent(wrap::PyPlotFigWrapper) = PyPlot.figure(wrap.fig.o[:number]) makePyPlotCurrent(wrap::PyPlotFigWrapper) = PyPlot.figure(wrap.fig.o[:number])
makePyPlotCurrent(wrap::PyPlotAxisWrapper) = PyPlot.sca(wrap.ax.o) makePyPlotCurrent(wrap::PyPlotAxisWrapper) = nothing #PyPlot.sca(wrap.ax.o)
makePyPlotCurrent(plt::Plot{PyPlotPackage}) = makePyPlotCurrent(plt.o) makePyPlotCurrent(plt::Plot{PyPlotPackage}) = makePyPlotCurrent(plt.o)
@ -341,7 +341,8 @@ function updatePlotItems(plt::Plot{PyPlotPackage}, d::Dict)
# PyPlot.sca(ax) # PyPlot.sca(ax)
# title and axis labels # title and axis labels
haskey(d, :title) && PyPlot.title(d[:title]) # haskey(d, :title) && PyPlot.title(d[:title])
haskey(d, :title) && ax[:set_title](d[:title])
haskey(d, :xlabel) && ax[:set_xlabel](d[:xlabel]) haskey(d, :xlabel) && ax[:set_xlabel](d[:xlabel])
if haskey(d, :ylabel) if haskey(d, :ylabel)
ax[:set_ylabel](d[:ylabel]) ax[:set_ylabel](d[:ylabel])

View File

@ -46,19 +46,11 @@ function plot(args...; kw...)
pkg = backend() pkg = backend()
d = Dict(kw) d = Dict(kw)
preprocessArgs!(d) preprocessArgs!(d)
dumpdict(d, "After plot preprocessing") dumpdict(d, "After plot preprocessing")
# # ensure we're passing in an RGB
# if haskey(d, :background_color)
# d[:background_color] = convertColor(d[:background_color])
# end
plt = plot(pkg; getPlotArgs(pkg, d, 1)...) # create a new, blank plot plt = plot(pkg; getPlotArgs(pkg, d, 1)...) # create a new, blank plot
delete!(d, :background_color) delete!(d, :background_color)
# print(d)
# return plt
plot!(plt, args...; d...) # add to it plot!(plt, args...; d...) # add to it
end end
@ -82,10 +74,6 @@ end
# this adds to a specific plot... most plot commands will flow through here # this adds to a specific plot... most plot commands will flow through here
function plot!(plt::Plot, args...; kw...) function plot!(plt::Plot, args...; kw...)
# println(plt)
# println(args)
# println(kw)
d = Dict(kw) d = Dict(kw)
preprocessArgs!(d) preprocessArgs!(d)
@ -93,21 +81,13 @@ function plot!(plt::Plot, args...; kw...)
warnOnUnsupportedArgs(plt.backend, d) warnOnUnsupportedArgs(plt.backend, d)
# handle a "group by" mechanism. # grouping
# group = get(d, :group, nothing)
# if group == nothing
# groupargs = []
# else
# if haskey(d, :subplot)
# groupargs = extractGroupArgs(group, d[:dataframe])
# end
groupargs = get(d, :group, nothing) == nothing ? [] : [extractGroupArgs(d[:group], args...)] groupargs = get(d, :group, nothing) == nothing ? [] : [extractGroupArgs(d[:group], args...)]
# 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)
preparePlotUpdate(plt) preparePlotUpdate(plt)
# get the list of dictionaries, one per series # get the list of dictionaries, one per series
# dumpdict(d, "before createKWargsList")
kwList, xmeta, ymeta = createKWargsList(plt, groupargs..., args...; d...) kwList, xmeta, ymeta = createKWargsList(plt, groupargs..., args...; d...)
# if we were able to extract guide information from the series inputs, then update the plot # if we were able to extract guide information from the series inputs, then update the plot
@ -136,11 +116,11 @@ function plot!(plt::Plot, args...; kw...)
warnOnUnsupportedScales(plt.backend, d) warnOnUnsupportedScales(plt.backend, d)
dumpdict(d, "Updating plot items")
# add title, axis labels, ticks, etc # add title, axis labels, ticks, etc
if !haskey(d, :subplot) if !haskey(d, :subplot)
d = merge!(plt.initargs, d) d = merge!(plt.initargs, d)
dumpdict(d, "Updating plot items")
updatePlotItems(plt, d) updatePlotItems(plt, d)
end end
current(plt) current(plt)
@ -161,25 +141,19 @@ end
function setTicksFromStringVector(d::Dict, di::Dict, sym::Symbol, ticksym::Symbol) function setTicksFromStringVector(d::Dict, di::Dict, sym::Symbol, ticksym::Symbol)
# if the x or y values are strings, set ticks to the unique values, and x/y to the indices of the ticks # if the x or y values are strings, set ticks to the unique values, and x/y to the indices of the ticks
# @show sym di
v = di[sym] v = di[sym]
# @show v
isa(v, AbstractArray) || return isa(v, AbstractArray) || return
T = eltype(v) T = eltype(v)
# @show T
if T <: @compat(AbstractString) || (!isempty(T.types) && all(x -> x <: @compat(AbstractString), T.types)) if T <: @compat(AbstractString) || (!isempty(T.types) && all(x -> x <: @compat(AbstractString), T.types))
# @show sym ticksym di[sym]
ticks = unique(di[sym]) ticks = unique(di[sym])
# @show ticks
di[sym] = Int[findnext(ticks, v, 1) for v in di[sym]] di[sym] = Int[findnext(ticks, v, 1) for v in di[sym]]
if !haskey(d, ticksym) || d[ticksym] == :auto if !haskey(d, ticksym) || d[ticksym] == :auto
d[ticksym] = (collect(1:length(ticks)), UTF8String[t for t in ticks]) d[ticksym] = (collect(1:length(ticks)), UTF8String[t for t in ticks])
end end
end end
# @show sym ticksym di[sym] d[ticksym]
end end
# -------------------------------------------------------------------- # --------------------------------------------------------------------

View File

@ -200,62 +200,25 @@ end
# NOTE: for the subplot calls building from existing plots, we need the first plot to be separate to ensure dispatch calls this instead of the more general subplot(args...; kw...) # NOTE: for the subplot calls building from existing plots, we need the first plot to be separate to ensure dispatch calls this instead of the more general subplot(args...; kw...)
# grid layout # grid layout
# function subplot{P}(plt1::Plot{P}, plts::Plot{P}...; nr::Integer = -1, nc::Integer = -1, link = false, linkx = false, linky = false)
function subplot{P}(plt1::Plot{P}, plts::Plot{P}...; kw...) function subplot{P}(plt1::Plot{P}, plts::Plot{P}...; kw...)
d = Dict(kw) d = Dict(kw)
layout = subplotlayout(length(plts)+1, get(d, :nr, -1), get(d, :nc, -1)) layout = subplotlayout(length(plts)+1, get(d, :nr, -1), get(d, :nc, -1))
subplot(vcat(plt1, plts...), layout, d) #, link || linkx, link || linky) subplot(vcat(plt1, plts...), layout, d)
end end
# explicit layout # explicit layout
function subplot{P,I<:Integer}(pltsPerRow::AVec{I}, plt1::Plot{P}, plts::Plot{P}...; kw...) #link = false, linkx = false, linky = false) function subplot{P,I<:Integer}(pltsPerRow::AVec{I}, plt1::Plot{P}, plts::Plot{P}...; kw...)
layout = subplotlayout(pltsPerRow) layout = subplotlayout(pltsPerRow)
subplot(vcat(plt1, plts...), layout, Dict(kw)) #, link || linkx, link || linky) subplot(vcat(plt1, plts...), layout, Dict(kw))
end end
# this will be called internally # this will be called internally
function subplot{P<:PlottingPackage}(plts::AVec{Plot{P}}, layout::SubplotLayout, d::Dict) #, linkx::Bool, linky::Bool) function subplot{P<:PlottingPackage}(plts::AVec{Plot{P}}, layout::SubplotLayout, d::Dict)
p = length(layout) p = length(layout)
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
# for s in (:linkx, :linky, :linkfunc)
# if haskey(d, s)
# setfield!(subplt, s, d[s])
# delete!(d, s)
# end
# end
preprocessSubplot(subplt, d) 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) postprocessSubplot(subplt, d)
subplt subplt
@ -288,11 +251,9 @@ function postprocessSubplot(subplt::Subplot, d::Dict)
# 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)
# get the full initargs, overriding any new settings # get the full initargs, overriding any new settings
# TODO: should this be part of the main `plot` command in plot.jl??? di = copy(merge!(plt.initargs, d))
di = merge!(plt.initargs, copy(d))
for (k,v) in di for (k,v) in di
if typeof(v) <: AVec if typeof(v) <: AVec
@ -339,16 +300,6 @@ function subplot!(subplt::Subplot, args...; kw...)
d = Dict(kw) d = Dict(kw)
preprocessSubplot(subplt, d) preprocessSubplot(subplt, d)
# preprocessArgs!(d)
# dumpdict(d, "After subplot! preprocessing")
# # process links. TODO: extract to separate function
# for s in (:linkx, :linky, :linkfunc)
# if haskey(d, s)
# setfield!(subplt, s, d[s])
# delete!(d, s)
# 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
@ -386,40 +337,10 @@ function subplot!(subplt::Subplot, args...; kw...)
end end
dumpdict(di, "subplot! kwList $i") dumpdict(di, "subplot! kwList $i")
plot!(plt; di...) _plot_from_subplot!(plt; di...)
end end
postprocessSubplot(subplt, d) 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)
# if !subplt.initialized
# subplt.initialized = buildSubplotObject!(subplt, false)
# # subplt.initialized = true
# 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
# subplt.linkx && linkAxis(subplt, true)
# subplt.linky && linkAxis(subplt, false)
# # set this to be current
# current(subplt)
# # --- end extract ----
# show it automatically? # show it automatically?
if haskey(d, :show) && d[:show] if haskey(d, :show) && d[:show]
@ -430,3 +351,19 @@ function subplot!(subplt::Subplot, args...; kw...)
end end
function _plot_from_subplot!(plt::Plot, args...; kw...)
d = Dict(kw)
setTicksFromStringVector(d, d, :x, :xticks)
setTicksFromStringVector(d, d, :y, :yticks)
dumpdict(d, "Plot from subplot")
plot!(plt.backend, plt; d...)
addAnnotations(plt, d)
warnOnUnsupportedScales(plt.backend, d)
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB