diff --git a/src/args.jl b/src/args.jl index b84abab5..8ead5bec 100644 --- a/src/args.jl +++ b/src/args.jl @@ -19,7 +19,7 @@ const TYPES = [:line, :ohlc, ] const STYLES = [:solid, :dash, :dot, :dashdot, :dashdotdot] -const MARKERS = [:ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon] +const MARKERS = [:ellipse, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon, :octagon] const ALL_AXES = vcat(:auto, AXES) const ALL_TYPES = vcat(:none, TYPES) @@ -40,54 +40,56 @@ subplotSupported() = subplotSupported(plotter()) # ----------------------------------------------------------------------------- -const PLOT_DEFAULTS = Dict{Symbol, Any}() +const _seriesDefaults = Dict{Symbol, Any}() # series-specific -PLOT_DEFAULTS[:axis] = :left -PLOT_DEFAULTS[:color] = :auto -PLOT_DEFAULTS[:label] = "AUTO" -PLOT_DEFAULTS[:width] = 1 -PLOT_DEFAULTS[:linetype] = :line -PLOT_DEFAULTS[:linestyle] = :solid -PLOT_DEFAULTS[:marker] = :none -PLOT_DEFAULTS[:markercolor] = :match -PLOT_DEFAULTS[:markersize] = 6 -PLOT_DEFAULTS[:nbins] = 100 # number of bins for heatmaps and hists -PLOT_DEFAULTS[:heatmap_c] = (0.15, 0.5) -PLOT_DEFAULTS[:fillto] = nothing # fills in the area -PLOT_DEFAULTS[:reg] = false # regression line? +_seriesDefaults[:axis] = :left +_seriesDefaults[:color] = :auto +_seriesDefaults[:label] = "AUTO" +_seriesDefaults[:width] = 1 +_seriesDefaults[:linetype] = :line +_seriesDefaults[:linestyle] = :solid +_seriesDefaults[:marker] = :none +_seriesDefaults[:markercolor] = :match +_seriesDefaults[:markersize] = 6 +_seriesDefaults[:nbins] = 100 # number of bins for heatmaps and hists +_seriesDefaults[:heatmap_c] = (0.15, 0.5) +_seriesDefaults[:fillto] = nothing # fills in the area +_seriesDefaults[:reg] = false # regression line? +_seriesDefaults[:group] = nothing +_seriesDefaults[:ribbon] = nothing +_seriesDefaults[:args] = [] # additional args to pass to the backend +_seriesDefaults[:kwargs] = [] # additional keyword args to pass to the backend + # note: can be Vector{Dict} or Vector{Tuple} + + +const _plotDefaults = Dict{Symbol, Any}() # plot globals -PLOT_DEFAULTS[:title] = "" -PLOT_DEFAULTS[:xlabel] = "" -PLOT_DEFAULTS[:ylabel] = "" -PLOT_DEFAULTS[:yrightlabel] = "" -PLOT_DEFAULTS[:legend] = true -# PLOT_DEFAULTS[:background_color] = nothing -# PLOT_DEFAULTS[:xticks] = true -# PLOT_DEFAULTS[:yticks] = true -PLOT_DEFAULTS[:size] = (600,400) -PLOT_DEFAULTS[:windowtitle] = "Plots.jl" -# PLOT_DEFAULTS[:show] = true +_plotDefaults[:title] = "" +_plotDefaults[:xlabel] = "" +_plotDefaults[:ylabel] = "" +_plotDefaults[:yrightlabel] = "" +_plotDefaults[:legend] = true +_plotDefaults[:background_color] = colorant"white" +_plotDefaults[:xticks] = true +_plotDefaults[:yticks] = true +_plotDefaults[:size] = (600,400) +_plotDefaults[:windowtitle] = "Plots.jl" +_plotDefaults[:show] = false -PLOT_DEFAULTS[:args] = [] # additional args to pass to the backend -PLOT_DEFAULTS[:kwargs] = [] # additional keyword args to pass to the backend - # note: can be Vector{Dict} or Vector{Tuple} + + +# const seriesKeys = [:axis, :color, :label, :width, :linetype, :linestyle, :marker, :markercolor, :markersize, :nbins, :heatmap_c, :fillto, :reg, :group, :ribbon] +# const plotKeys = [:title, :xlabel, :ylabel, :yrightlabel, :legend, :background_color, :xticks, :yticks, :size, :windowtitle, :show] # TODO: x/y scales -const ARGS = sort(collect(keys(PLOT_DEFAULTS))) +const ARGS = sort(collect(intersect(keys(_seriesDefaults), keys(_plotDefaults)))) supportedArgs(::PlottingPackage) = ARGS supportedArgs() = supportedArgs(plotter()) -# ----------------------------------------------------------------------------- - -plotDefault(sym::Symbol) = PLOT_DEFAULTS[sym] -function plotDefault!(sym::Symbol, val) - PLOT_DEFAULTS[sym] = val -end - # ----------------------------------------------------------------------------- makeplural(s::Symbol) = Symbol(string(s,"s")) @@ -98,6 +100,92 @@ autopick(notarr, idx::Integer) = notarr autopick_ignore_none_auto(arr::AVec, idx::Integer) = autopick(setdiff(arr, [:none, :auto]), idx) autopick_ignore_none_auto(notarr, idx::Integer) = notarr +# ----------------------------------------------------------------------------- + +# Alternate args + +const keyAliases = Dict( + :c => :color, + :l => :label, + :w => :width, + :linewidth => :width, + :type => :linetype, + :t => :linetype, + :style => :linestyle, + :s => :linestyle, + :m => :marker, + :mc => :markercolor, + :mcolor => :markercolor, + :ms => :markersize, + :msize => :markersize, + :nb => :nbins, + :nbin => :nbins, + :fill => :fillto, + :g => :group, + :r => :ribbon, + :xlab => :xlabel, + :ylab => :ylabel, + :yrlab => :yrightlabel, + :ylabr => :yrightlabel, + :y2lab => :yrightlabel, + :ylab2 => :yrightlabel, + :ylabelright => :yrightlabel, + :ylabel2 => :yrightlabel, + :y2label => :yrightlabel, + :leg => :legend, + :bg => :background_color, + :bgcolor => :background_color, + :bg_color => :background_color, + :background => :background_color, + :windowsize => :size, + :wsize => :size, + :wtitle => :windowtitle, + :display => :show, + ) + +# add all pluralized forms to the keyAliases dict +for arg in keys(_seriesDefaults) + keyAliases[makeplural(arg)] = arg +end + + +function replaceAliases!(d::Dict) + for (k,v) in d + if haskey(keyAliases, k) + d[keyAliases[k]] = v + delete!(d, k) + end + end +end + + +# ----------------------------------------------------------------------------- + +# update the defaults globally + +function plotDefault(k::Symbol) + if haskey(_seriesDefaults, k) + return _seriesDefaults[k] + elseif haskey(_plotDefaults, k) + return _plotDefaults[k] + else + error("Unknown key: ", k) + end +end + +function plotDefault!(k::Symbol, v) + if haskey(_seriesDefaults, k) + _seriesDefaults[k] = v + elseif haskey(_plotDefaults, k) + _plotDefaults[k] = v + else + error("Unknown key: ", k) + end +end + +# ----------------------------------------------------------------------------- + + # converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically # note: if plt is nothing, we aren't doing anything with the color anyways function getRGBColor(c, n::Int = 0) @@ -122,8 +210,7 @@ function getRGBColor(c, n::Int = 0) c end -# const ALT_ARG_NAMES = Dict{Tuple{Symbol,Symbol}, Any}() -# ALT_ARG_NAMES[(:linetype, :scatter)] = :scatter + function warnOnUnsupported(pkg::PlottingPackage, d::Dict) d[:axis] in supportedAxes(pkg) || warn("axis $(d[:axis]) is unsupported with $pkg. Choose from: $(supportedAxes(pkg))") @@ -133,93 +220,173 @@ function warnOnUnsupported(pkg::PlottingPackage, d::Dict) end -# note: idx is the index of this series within this call, n is the index of the series from all calls to plot/subplot -function getPlotKeywordArgs(pkg::PlottingPackage, kw, idx::Int, n::Int) +function getPlotArgs(pkg::PlottingPackage, kw, idx::Int) d = Dict(kw) - # # replace alternate names - # for tup in kw - # if haskey(ALT_ARG_NAMES, tup) - # d[tup[1]] = ALT_ARG_NAMES[tup] - # end - # end - - # default to a white background, but only on the initial call (so we don't change the background automatically) - if haskey(d, :background_color) - d[:background_color] = getRGBColor(d[:background_color]) - elseif n == 0 - d[:background_color] = colorant"white" + # add defaults? + for k in keys(_plotDefaults) + if haskey(d, k) + v = d[k] + if isa(v, AbstractVector) && !isempty(v) + # we got a vector, cycling through + d[k] = autopick(v, idx) + end + else + d[k] = _plotDefaults[k] + end end - # fill in d with either 1) plural value, 2) value, 3) default - for k in keys(PLOT_DEFAULTS) - plural = makeplural(k) - if !haskey(d, k) - if n == 0 || k != :size - d[k] = haskey(d, plural) ? autopick(d[plural], idx) : PLOT_DEFAULTS[k] + # convert color + d[:background_color] = getRGBColor(d[:background_color]) + + # no need for these + delete!(d, :x) + delete!(d, :y) + + d +end + + + +# note: idx is the index of this series within this call, n is the index of the series from all calls to plot/subplot +function getSeriesArgs(pkg::PlottingPackage, kw, idx::Int, n::Int) + d = Dict(kw) + + # add defaults? + for k in keys(_seriesDefaults) + if haskey(d, k) + v = d[k] + if isa(v, AbstractVector) && !isempty(v) + # we got a vector, cycling through + d[k] = autopick(v, idx) end + else + d[k] = _seriesDefaults[k] end - delete!(d, plural) end # auto-pick - if n > 0 - if d[:axis] == :auto - d[:axis] = autopick_ignore_none_auto(supportedAxes(pkg), n) - end - # if d[:linetype] == :auto - # d[:linetype] = autopick_ignore_none_auto(supportedTypes(pkg), n) - # end - if d[:linestyle] == :auto - d[:linestyle] = autopick_ignore_none_auto(supportedStyles(pkg), n) - end - if d[:marker] == :auto - d[:marker] = autopick_ignore_none_auto(supportedMarkers(pkg), n) - end - + if d[:axis] == :auto + d[:axis] = autopick_ignore_none_auto(supportedAxes(pkg), n) + end + if d[:linestyle] == :auto + d[:linestyle] = autopick_ignore_none_auto(supportedStyles(pkg), n) + end + if d[:marker] == :auto + d[:marker] = autopick_ignore_none_auto(supportedMarkers(pkg), n) end - # # swap out dots for no line and a marker - # if haskey(d, :linetype) && d[:linetype] == :scatter - # d[:linetype] = :none - # if d[:marker] == :none - # d[:marker] = :ellipse - # end - # end + # update color + d[:color] = getRGBColor(d[:color], n) + # update markercolor + mc = d[:markercolor] + mc = (mc == :match ? d[:color] : getRGBColor(mc, n)) + d[:markercolor] = mc - - # handle plot initialization differently - if n == 0 - delete!(d, :x) - delete!(d, :y) - else - # once the plot is created, we can get line/marker colors - - # update color - d[:color] = getRGBColor(d[:color], n) - - # update markercolor - mc = d[:markercolor] - mc = (mc == :match ? d[:color] : getRGBColor(mc, n)) - d[:markercolor] = mc - - # set label - label = d[:label] - label = (label == "AUTO" ? "y$n" : label) - if d[:axis] == :right && length(label) >= 4 && label[end-3:end] != " (R)" - label = string(label, " (R)") - end - d[:label] = label - - warnOnUnsupported(pkg, d) + # set label + label = d[:label] + label = (label == "AUTO" ? "y$n" : label) + if d[:axis] == :right && length(label) >= 4 && label[end-3:end] != " (R)" + label = string(label, " (R)") end + d[:label] = label + + warnOnUnsupported(pkg, d) d end + +# # note: idx is the index of this series within this call, n is the index of the series from all calls to plot/subplot +# function getPlotKeywordArgs(pkg::PlottingPackage, kw, idx::Int, n::Int) +# d = Dict(kw) + +# # # replace alternate names +# # for tup in kw +# # if haskey(ALT_ARG_NAMES, tup) +# # d[tup[1]] = ALT_ARG_NAMES[tup] +# # end +# # end + +# # default to a white background, but only on the initial call (so we don't change the background automatically) +# if haskey(d, :background_color) +# d[:background_color] = getRGBColor(d[:background_color]) +# elseif n == 0 +# d[:background_color] = colorant"white" +# end + +# # fill in d with either 1) plural value, 2) value, 3) default +# for k in keys(PLOT_DEFAULTS) +# plural = makeplural(k) +# if !haskey(d, k) +# if n == 0 || k != :size +# d[k] = haskey(d, plural) ? autopick(d[plural], idx) : PLOT_DEFAULTS[k] +# end +# end +# delete!(d, plural) +# end + +# # auto-pick +# if n > 0 +# if d[:axis] == :auto +# d[:axis] = autopick_ignore_none_auto(supportedAxes(pkg), n) +# end +# # if d[:linetype] == :auto +# # d[:linetype] = autopick_ignore_none_auto(supportedTypes(pkg), n) +# # end +# if d[:linestyle] == :auto +# d[:linestyle] = autopick_ignore_none_auto(supportedStyles(pkg), n) +# end +# if d[:marker] == :auto +# d[:marker] = autopick_ignore_none_auto(supportedMarkers(pkg), n) +# end + +# end + +# # # swap out dots for no line and a marker +# # if haskey(d, :linetype) && d[:linetype] == :scatter +# # d[:linetype] = :none +# # if d[:marker] == :none +# # d[:marker] = :ellipse +# # end +# # end + + + +# # handle plot initialization differently +# if n == 0 +# delete!(d, :x) +# delete!(d, :y) +# else +# # once the plot is created, we can get line/marker colors + +# # update color +# d[:color] = getRGBColor(d[:color], n) + +# # update markercolor +# mc = d[:markercolor] +# mc = (mc == :match ? d[:color] : getRGBColor(mc, n)) +# d[:markercolor] = mc + +# # set label +# label = d[:label] +# label = (label == "AUTO" ? "y$n" : label) +# if d[:axis] == :right && length(label) >= 4 && label[end-3:end] != " (R)" +# label = string(label, " (R)") +# end +# d[:label] = label + +# warnOnUnsupported(pkg, d) +# end + + +# d +# end + + # ----------------------------------------------------------------------------- diff --git a/src/backends/gadfly.jl b/src/backends/gadfly.jl index fd8871cf..3185a298 100644 --- a/src/backends/gadfly.jl +++ b/src/backends/gadfly.jl @@ -11,7 +11,7 @@ supportedArgs(::GadflyPackage) = setdiff(ARGS, [:heatmap_c, :fillto, :pos]) supportedAxes(::GadflyPackage) = setdiff(ALL_AXES, [:right]) supportedTypes(::GadflyPackage) = [:none, :line, :step, :sticks, :scatter, :heatmap, :hexbin, :hist, :bar, :hline, :vline, :ohlc] supportedStyles(::GadflyPackage) = [:auto, :solid] -supportedMarkers(::GadflyPackage) = [:none, :auto, :rect, :ellipse, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon] +supportedMarkers(::GadflyPackage) = [:none, :auto, :rect, :ellipse, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star1, :star2, :hexagon, :octagon] include("gadfly_shapes.jl") diff --git a/src/backends/gadfly_shapes.jl b/src/backends/gadfly_shapes.jl index 88d52a1f..228afe74 100644 --- a/src/backends/gadfly_shapes.jl +++ b/src/backends/gadfly_shapes.jl @@ -43,6 +43,9 @@ function createGadflyAnnotation(d::Dict) elseif marker == :hexagon shape = hexagon(x, y, sz) + elseif marker == :octagon + shape = octagon(x, y, sz) + else # make circles sz = 0.8 * d[:markersize] * Gadfly.px @@ -203,9 +206,39 @@ function star2(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray, scalar = end + function hexagon(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray) n = max(length(xs), length(ys), length(rs)) + polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n) + for i in 1:n + x = Compose.x_measure(xs[mod1(i, length(xs))]) + y = Compose.y_measure(ys[mod1(i, length(ys))]) + r = rs[mod1(i, length(rs))] + u = 0.6r + + # make a "plus sign" + polys[i] = Tuple{Compose.Measure, Compose.Measure}[ + (x-r, y-u), (x-r, y+u), # L edge + # (x-u, y+u), # BL inside + # (x-u, y+r), (x+u, y+r), # B edge + (x, y+r), + # (x+u, y+u), # BR inside + (x+r, y+u), (x+r, y-u), # R edge + (x, y-r) + # (x+u, y-u), # TR inside + # (x+u, y-r), (x-u, y-r), # T edge + # (x-u, y-u) # TL inside + ] + end + + return Gadfly.polygon(polys) +end + + +function octagon(xs::AbstractArray, ys::AbstractArray, rs::AbstractArray) + n = max(length(xs), length(ys), length(rs)) + polys = Vector{Vector{Tuple{Compose.Measure, Compose.Measure}}}(n) for i in 1:n x = Compose.x_measure(xs[mod1(i, length(xs))]) diff --git a/src/backends/immerse.jl b/src/backends/immerse.jl index 684a85bc..44c2fd81 100644 --- a/src/backends/immerse.jl +++ b/src/backends/immerse.jl @@ -78,7 +78,7 @@ end function buildSubplotObject!(::ImmersePackage, subplt::Subplot) # create the Gtk window with vertical box vsep - d = subplt.initargs + d = subplt.initargs[1] w,h = d[:size] vsep = Gtk.GtkBoxLeaf(:v) win = Gtk.GtkWindowLeaf(vsep, d[:windowtitle], w, h) diff --git a/src/backends/qwt.jl b/src/backends/qwt.jl index 615ad426..23f16854 100644 --- a/src/backends/qwt.jl +++ b/src/backends/qwt.jl @@ -12,7 +12,9 @@ supportedTypes(::QwtPackage) = [:none, :line, :step, :stepinverted, :sticks, :sc function adjustQwtKeywords(iscreating::Bool; kw...) d = Dict(kw) - d[:heatmap_n] = d[:nbins] + if !iscreating + d[:heatmap_n] = d[:nbins] + end if d[:linetype] == :hexbin d[:linetype] = :heatmap @@ -30,7 +32,8 @@ function adjustQwtKeywords(iscreating::Bool; kw...) end function plot(pkg::QwtPackage; kw...) - d = adjustQwtKeywords(true; kw...) + d = Dict(kw) + # d = adjustQwtKeywords(true; kw...) o = Qwt.plot(zeros(0,0); d..., show=false) plt = Plot(o, pkg, 0, d, Dict[]) plt @@ -63,7 +66,7 @@ function buildSubplotObject!(::QwtPackage, subplt::Subplot) i += rowcnt end subplt.o = Qwt.vsplitter(rows...) - Qwt.resizewidget(subplt.o, subplt.initargs[:size]...) + Qwt.resizewidget(subplt.o, subplt.initargs[1][:size]...) Qwt.moveToLastScreen(subplt.o) # hack so it goes to my center monitor... sorry end diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 73a20586..74672c6d 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -99,7 +99,7 @@ function plot(pkg::UnicodePlotsPackage; kw...) plt = Plot(nothing, pkg, 0, Dict(kw), Dict[]) # do we want to give a new default size? - if !haskey(plt.initargs, :size) || plt.initargs[:size] == PLOT_DEFAULTS[:size] + if !haskey(plt.initargs, :size) || plt.initargs[:size] == _plotDefaults[:size] plt.initargs[:size] = (60,20) end diff --git a/src/plot.jl b/src/plot.jl index 5d390291..729998c6 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -88,7 +88,7 @@ When plotting multiple lines, you can give every line the same trait by using th # this creates a new plot with args/kw and sets it to be the current plot function plot(args...; kw...) pkg = plotter() - plt = plot(pkg; getPlotKeywordArgs(pkg, kw, 1, 0)...) # create a new, blank plot + plt = plot(pkg; getPlotArgs(pkg, kw, 1)...) # create a new, blank plot plot!(plt, args...; kw...) # add to it end @@ -112,13 +112,16 @@ end # this adds to a specific plot... most plot commands will flow through here function plot!(plt::Plot, args...; kw...) + d = Dict(kw) + replaceAliases!(d) + # TODO: handle a "group by" mechanism. # will probably want to check for the :group kw param, and split into # index partitions/filters to be passed through to the next step. # Ideally we don't change the insides ot createKWargsList too much to # save from code repetition. We could consider adding a throw - kwList = createKWargsList(plt, args...; kw...) + kwList = createKWargsList(plt, args...; d...) for (i,d) in enumerate(kwList) plt.n += 1 plot!(plt.plotter, plt; d...) @@ -128,7 +131,6 @@ function plot!(plt::Plot, args...; kw...) # NOTE: lets ignore the show param and effectively use the semicolon at the end of the REPL statement # # do we want to show it? - # d = Dict(kw) # if haskey(d, :show) && d[:show] # display(plt) # end @@ -154,7 +156,7 @@ function createKWargsList(plt::PlottingObject; kw...) if !haskey(d, :x) d[:x] = 1:length(d[:y]) end - [getPlotKeywordArgs(plt.plotter, d, 1, plt.n + 1)] + [getSeriesArgs(plt.plotter, d, 1, plt.n + 1)] end @@ -165,7 +167,7 @@ end # create one series where y is vectors of numbers function createKWargsList{T<:Real}(plt::PlottingObject, y::AVec{T}; kw...) - d = getPlotKeywordArgs(plt.plotter, kw, 1, plt.n + 1) + d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) d[:x] = 1:length(y) d[:y] = y [d] @@ -174,7 +176,7 @@ end # create one series where x/y are vectors of numbers function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AVec{T}, y::AVec{S}; kw...) @assert length(x) == length(y) - d = getPlotKeywordArgs(plt.plotter, kw, 1, plt.n + 1) + d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) d[:x] = x d[:y] = y [d] @@ -185,7 +187,7 @@ function createKWargsList{T<:Real}(plt::PlottingObject, y::AMat{T}; kw...) n,m = size(y) ret = [] for i in 1:m - d = getPlotKeywordArgs(plt.plotter, kw, i, plt.n + i) + d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d[:x] = 1:n d[:y] = y[:,i] push!(ret, d) @@ -199,7 +201,7 @@ function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AVec{T}, y::A @assert length(x) == n ret = [] for i in 1:m - d = getPlotKeywordArgs(plt.plotter, kw, i, plt.n + i) + d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d[:x] = x d[:y] = y[:,i] push!(ret, d) @@ -213,7 +215,7 @@ function createKWargsList{T<:Real,S<:Real}(plt::PlottingObject, x::AMat{T}, y::A n,m = size(y) ret = [] for i in 1:m - d = getPlotKeywordArgs(plt.plotter, kw, i, plt.n + i) + d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d[:x] = x[:,i] d[:y] = y[:,i] push!(ret, d) @@ -228,7 +230,7 @@ end # create 1 series, y = f(x), x ∈ [xmin, xmax] function createKWargsList(plt::PlottingObject, f::Function, xmin::Real, xmax::Real; kw...) - d = getPlotKeywordArgs(plt.plotter, kw, 1, plt.n + 1) + d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) width = plt.initargs[:size][1] d[:x] = collect(linspace(xmin, xmax, width)) # we don't need more than the width d[:y] = map(f, d[:x]) @@ -242,7 +244,7 @@ function createKWargsList(plt::PlottingObject, fs::Vector{Function}, xmin::Real, width = plt.initargs[:size][1] x = collect(linspace(xmin, xmax, width)) # we don't need more than the width for i in 1:m - d = getPlotKeywordArgs(plt.plotter, kw, i, plt.n + i) + d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d[:x] = x d[:y] = map(fs[i], x) push!(ret, d) @@ -252,7 +254,7 @@ end # create 1 series, x = fx(u), y = fy(u); u ∈ [umin, umax] function createKWargsList(plt::PlottingObject, fx::Function, fy::Function, umin::Real, umax::Real; kw...) - d = getPlotKeywordArgs(plt.plotter, kw, 1, plt.n + 1) + d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) width = plt.initargs[:size][1] u = collect(linspace(umin, umax, width)) # we don't need more than the width d[:x] = map(fx, u) @@ -262,7 +264,7 @@ end # create 1 series, y = f(x) function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec{T}, f::Function; kw...) - d = getPlotKeywordArgs(plt.plotter, kw, 1, plt.n + 1) + d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) d[:x] = x d[:y] = map(f, x) [d] @@ -274,7 +276,7 @@ function createKWargsList{T<:Real}(plt::PlottingObject, x::AMat{T}, f::Function; n,m = size(x) ret = [] for i in 1:m - d = getPlotKeywordArgs(plt.plotter, kw, i, plt.n + i) + d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d[:x] = x[:,i] d[:y] = map(f, d[:x]) push!(ret, d) @@ -294,7 +296,7 @@ function createKWargsList(plt::PlottingObject, y::AVec; kw...) m = length(y) ret = [] for i in 1:m - d = getPlotKeywordArgs(plt.plotter, kw, i, plt.n + i) + d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d[:x] = 1:length(y[i]) d[:y] = y[i] push!(ret, d) @@ -314,7 +316,7 @@ function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec{T}, y::AVec; kw. m = length(y) ret = [] for i in 1:m - d = getPlotKeywordArgs(plt.plotter, kw, i, plt.n + i) + d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d[:x] = x d[:y] = getyvec(x, y[i]) push!(ret, d) @@ -328,7 +330,7 @@ function createKWargsList{T<:Real}(plt::PlottingObject, x::AVec, y::AMat{T}; kw. @assert length(x) == m ret = [] for i in 1:m - d = getPlotKeywordArgs(plt.plotter, kw, i, plt.n + i) + d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d[:x] = x[i] d[:y] = getyvec(x[i], y[:,i]) push!(ret, d) @@ -342,7 +344,7 @@ function createKWargsList(plt::PlottingObject, x::AVec, y::AVec; kw...) m = length(y) ret = [] for i in 1:m - d = getPlotKeywordArgs(plt.plotter, kw, i, plt.n + i) + d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d[:x] = x[i] d[:y] = getyvec(x[i], y[i]) push!(ret, d) @@ -354,7 +356,7 @@ end function createKWargsList(plt::PlottingObject, n::Integer; kw...) ret = [] for i in 1:n - d = getPlotKeywordArgs(plt.plotter, kw, i, plt.n + i) + d = getSeriesArgs(plt.plotter, kw, i, plt.n + i) d[:x] = zeros(0) d[:y] = zeros(0) push!(ret, d) @@ -366,7 +368,7 @@ end createKWargsList{T<:Tuple}(plt::PlottingObject, y::AVec{T}; kw...) = createKWargsList(plt, 1:length(y), y; kw...) function createKWargsList{S<:Real, T<:Tuple}(plt::PlottingObject, x::AVec{S}, y::AVec{T}; kw...) - d = getPlotKeywordArgs(plt.plotter, kw, 1, plt.n + 1) + d = getSeriesArgs(plt.plotter, kw, 1, plt.n + 1) d[:x] = x d[:y] = y [d] diff --git a/src/subplot.jl b/src/subplot.jl index b41adcab..f985eb1e 100644 --- a/src/subplot.jl +++ b/src/subplot.jl @@ -71,14 +71,21 @@ function subplot(args...; kw...) # initialize the individual plots pkg = plotter() - tmpd = getPlotKeywordArgs(pkg, kw, 1, 0) - # shouldShow = tmpd[:show] - # tmpd[:show] = false - plts = Plot[plot(pkg; tmpd...) for i in 1:length(layout)] - # tmpd[:show] = shouldShow + plts = Plot[] + ds = Dict[] + for i in 1:length(layout) + push!(ds, getPlotArgs(pkg, kw, i)) + push!(plts, plot(pkg; ds[i]...)) + end + + # tmpd = getPlotKeywordArgs(pkg, kw, 1, 0) # TODO: this should happen in the plot creation loop... think... what if we want to set a title per subplot?? + # # shouldShow = tmpd[:show] + # # tmpd[:show] = false + # plts = Plot[plot(pkg; tmpd...) for i in 1:length(layout)] + # # tmpd[:show] = shouldShow # create the object and do the plotting - subplt = Subplot(nothing, plts, pkg, length(layout), 0, layout, tmpd, false) + subplt = Subplot(nothing, plts, pkg, length(layout), 0, layout, ds, false) subplot!(subplt, args...; kw...) subplt diff --git a/src/types.jl b/src/types.jl index e4cf9115..ef085251 100644 --- a/src/types.jl +++ b/src/types.jl @@ -29,6 +29,6 @@ type Subplot <: PlottingObject p::Int # number of plots n::Int # number of series layout::SubplotLayout - initargs::Dict + initargs::Vector{Dict} initialized::Bool end \ No newline at end of file