diff --git a/src/Plots.jl b/src/Plots.jl index 93e313f2..a112bb2e 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -28,45 +28,14 @@ export # --------------------------------------------------------- -typealias AVec AbstractVector -typealias AMat AbstractMatrix - -abstract PlottingObject -abstract PlottingPackage const IMG_DIR = Pkg.dir("Plots") * "/img/" # --------------------------------------------------------- -type Plot <: PlottingObject - o # the underlying object - plotter::PlottingPackage - n::Int # number of series -end - -Base.string(plt::Plot) = "Plot{$(plt.plotter) n=$(plt.n)}" -Base.print(io::IO, plt::Plot) = print(io, string(plt)) -Base.show(io::IO, plt::Plot) = print(io, string(plt)) - -getplot(plt::Plot, args...) = plt - -# --------------------------------------------------------- - -type CurrentPlot - nullableplot::Nullable{PlottingObject} -end -const CURRENT_PLOT = CurrentPlot(Nullable{PlottingObject}()) - -isplotnull() = isnull(CURRENT_PLOT.nullableplot) - -function currentPlot() - if isplotnull() - error("No current plot/subplot") - end - get(CURRENT_PLOT.nullableplot) -end -currentPlot!(plot::PlottingObject) = (CURRENT_PLOT.nullableplot = Nullable(plot)) +include("types.jl") +include("utils.jl") # --------------------------------------------------------- @@ -76,7 +45,6 @@ include("plotter.jl") # --------------------------------------------------------- -include("utils.jl") include("args.jl") include("plot.jl") include("subplot.jl") diff --git a/src/plot.jl b/src/plot.jl index 322f748a..3e4bb97b 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -1,4 +1,28 @@ +type CurrentPlot + nullableplot::Nullable{PlottingObject} +end +const CURRENT_PLOT = CurrentPlot(Nullable{PlottingObject}()) + +isplotnull() = isnull(CURRENT_PLOT.nullableplot) + +function currentPlot() + if isplotnull() + error("No current plot/subplot") + end + get(CURRENT_PLOT.nullableplot) +end +currentPlot!(plot::PlottingObject) = (CURRENT_PLOT.nullableplot = Nullable(plot)) + +# --------------------------------------------------------- + + +Base.string(plt::Plot) = "Plot{$(plt.plotter) n=$(plt.n)}" +Base.print(io::IO, plt::Plot) = print(io, string(plt)) +Base.show(io::IO, plt::Plot) = print(io, string(plt)) + +getplot(plt::Plot) = plt + doc""" The main plot command. Call `plotter!(:module)` to set the current plotting backend. @@ -75,12 +99,20 @@ end # this adds to a specific plot... most plot commands will flow through here function plot!(plt::Plot, args...; kw...) - # increment n if we're going directly to the package's plot method - if length(args) == 0 + # # increment n if we're going directly to the package's plot method + # if length(args) == 0 + # plt.n += 1 + # end + + # plot!(plt.plotter, plt, args...; kw...) + + + kwList = createKWargsList(plt, args...; kw...) + for (i,d) in enumerate(kwList) plt.n += 1 + plot!(plt.plotter, plt; d...) end - plot!(plt.plotter, plt, args...; kw...) currentPlot!(plt) # do we want to show it? @@ -93,7 +125,7 @@ function plot!(plt::Plot, args...; kw...) end # show/update the plot -function Base.display(plt::Plot) +function Base.display(plt::PlottingObject) display(plt.plotter, plt) end @@ -103,6 +135,11 @@ end doc"Build a vector of dictionaries which hold the keyword arguments for a call to plot!" +# no args... 1 series +function createKWargsList(plt::PlottingObject; kw...) + [getPlotKeywordArgs(kw, 1, plt.n + 1)] +end + # create one series where y is vectors of numbers function createKWargsList{T<:Real}(plt::PlottingObject, y::AVec{T}; kw...) d = getPlotKeywordArgs(kw, 1, plt.n + 1) @@ -245,15 +282,15 @@ end # ------------------------- -# most calls should flow through here now... we create a Dict with the keyword args for each series, and plot them -function plot!(pkg::PlottingPackage, plt::Plot, args...; kw...) - kwList = createKWargsList(plt, args...; kw...) - for (i,d) in enumerate(kwList) - plt.n += 1 - plot!(pkg, plt; d...) - end - plt -end +# # most calls should flow through here now... we create a Dict with the keyword args for each series, and plot them +# function plot!(pkg::PlottingPackage, plt::Plot, args...; kw...) +# kwList = createKWargsList(plt, args...; kw...) +# for (i,d) in enumerate(kwList) +# plt.n += 1 +# plot!(pkg, plt; d...) +# end +# plt +# end # ------------------------- diff --git a/src/qwt.jl b/src/qwt.jl index 07ee29e9..c64a1d6d 100644 --- a/src/qwt.jl +++ b/src/qwt.jl @@ -3,6 +3,8 @@ immutable QwtPackage <: PlottingPackage end +# ------------------------------- + function adjustQwtKeywords(iscreating::Bool; kw...) d = Dict(kw) d[:heatmap_n] = d[:nbins] @@ -36,6 +38,18 @@ function Base.display(::QwtPackage, plt::Plot) Qwt.showwidget(plt.o) end -savepng(::QwtPackage, plt::Plot, fn::String, args...) = Qwt.savepng(plt.o, fn) +# ------------------------------- + +savepng(::QwtPackage, plt::PlottingObject, fn::String, args...) = Qwt.savepng(plt.o, fn) + +# ------------------------------- # subplot(::QwtPackage, args...; kw...) = Qwt.subplot(args...; kw...) + +function Base.display(::QwtPackage, subplt::SubPlot) + for plt in subplt.plts + Qwt.refresh(plt.o) + end + Qwt.showwidget(subplt.o) +end + diff --git a/src/subplot.jl b/src/subplot.jl index 43ac4138..e34f5b86 100644 --- a/src/subplot.jl +++ b/src/subplot.jl @@ -1,8 +1,4 @@ -type SubPlotLayout - numplts::Int - rowcounts::AbstractVector{Int} -end # create a layout directly SubPlotLayout(rowcounts::AbstractVector{Int}) = SubPlotLayout(sum(rowcounts), rowcounts) @@ -40,30 +36,23 @@ Base.length(layout::SubPlotLayout) = layout.numplts # ------------------------------------------------------------ -type SubPlot <: PlottingObject - o # the underlying object - plts::Vector{Plot} # the individual plots - plotter::PlottingPackage - p::Int # number of plots - n::Int # number of series - layout::SubPlotLayout -end Base.string(subplt::SubPlot) = "SubPlot{$(subplt.plotter) p=$(subplt.p) n=$(subplt.n)}" Base.print(io::IO, subplt::SubPlot) = print(io, string(subplt)) Base.show(io::IO, subplt::SubPlot) = print(io, string(subplt)) -getplot(subplt::SubPlot, i::Int) = subplt.plts[mod1(i, subplt.p)] +getplot(subplt::SubPlot) = subplt.plts[mod1(subplt.n, subplt.p)] # ------------------------------------------------------------ doc""" -y = rand(100,3) -subplot(y; n = 3) # create an automatic grid, and let it figure out the numrows/numcols... will put plots 1 and 2 on the first row, and plot 3 by itself on the 2nd row -subplot(y; n = 3, numrows = 1) # create an automatic grid, but fix the number of rows to 1 (so there are n columns) -subplot(y; n = 3, numcols = 1) # create an automatic grid, but fix the number of columns to 1 (so there are n rows) -subplot(y; layout = [1, 2]) # explicit layout by row... plot #1 goes by itself in the first row, plots 2 and 3 split the 2nd row (note the n kw is unnecessary) +Create a series of plots: + y = rand(100,3) + subplot(y; n = 3) # create an automatic grid, and let it figure out the numrows/numcols... will put plots 1 and 2 on the first row, and plot 3 by itself on the 2nd row + subplot(y; n = 3, numrows = 1) # create an automatic grid, but fix the number of rows to 1 (so there are n columns) + subplot(y; n = 3, numcols = 1) # create an automatic grid, but fix the number of columns to 1 (so there are n rows) + subplot(y; layout = [1, 2]) # explicit layout by row... plot #1 goes by itself in the first row, plots 2 and 3 split the 2nd row (note the n kw is unnecessary) """ function subplot(args...; kw...) d = Dict(kw) @@ -91,28 +80,63 @@ function subplot(args...; kw...) subplot!(subplt, args...; kw...) end +doc""" +Adds to a subplot. +""" + +# current subplot +function subplot!(args...; kw...) + subplot!(currentPlot(), args...; kw...) +end -# # this creates a new plot with args/kw and sets it to be the current plot -# function plot(args...; kw...) -# plt = plot(plotter(); getPlotKeywordArgs(kw, 1, 0)...) # create a new, blank plot -# plot!(plt, args...; kw...) # add to it -# end +# not allowed: +function subplot!(plt::Plot, args...; kw...) + error("Can't call subplot! on a Plot!") +end -# # this adds to the current plot -# function plot!(args...; kw...) -# plot!(currentPlot(), args...; kw...) -# end + +# # this adds to a specific subplot... most plot commands will flow through here +function subplot!(subplt::SubPlot, args...; kw...) + kwList = createKWargsList(subplt, args...; kw...) + for (i,d) in enumerate(kwList) + subplt.n += 1 + plt = getplot(subplt) # get the Plot object where this series will be drawn + plot!(plt; d...) + end + + currentPlot!(subplt) + + # do we want to show it? + d = Dict(kw) + if haskey(d, :show) && d[:show] + display(subplt) + end + + subplt +end + + +# # # this creates a new plot with args/kw and sets it to be the current plot +# # function plot(args...; kw...) +# # plt = plot(plotter(); getPlotKeywordArgs(kw, 1, 0)...) # create a new, blank plot +# # plot!(plt, args...; kw...) # add to it +# # end + +# # # this adds to the current plot +# # function plot!(args...; kw...) +# # plot!(currentPlot(), args...; kw...) +# # end # # this adds to a specific plot... most plot commands will flow through here # function plot!(plt::Plot, args...; kw...) -# # increment n if we're going directly to the package's plot method -# if length(args) == 0 +# kwList = createKWargsList(plt, args...; kw...) +# for (i,d) in enumerate(kwList) # plt.n += 1 +# plot!(plt.plotter, plt; d...) # end -# plot!(plt.plotter, plt, args...; kw...) # currentPlot!(plt) # # do we want to show it? @@ -124,19 +148,4 @@ end # plt # end -# # show/update the plot -# function Base.display(plt::Plot) -# display(plt.plotter, plt) -# end - - -# # most calls should flow through here now... we create a Dict with the keyword args for each series, and plot them -# function plot!(pkg::PlottingPackage, plt::Plot, args...; kw...) -# kwList = createKWargsList(plt, args...; kw...) -# for (i,d) in enumerate(kwList) -# plt.n += 1 -# plot!(pkg, plt; d...) -# end -# plt -# end diff --git a/src/types.jl b/src/types.jl new file mode 100644 index 00000000..6bf4fab9 --- /dev/null +++ b/src/types.jl @@ -0,0 +1,28 @@ + +typealias AVec AbstractVector +typealias AMat AbstractMatrix + +abstract PlottingObject +abstract PlottingPackage + +type Plot <: PlottingObject + o # the underlying object + plotter::PlottingPackage + n::Int # number of series +end + + +type SubPlotLayout + numplts::Int + rowcounts::AbstractVector{Int} +end + + +type SubPlot <: PlottingObject + o # the underlying object + plts::Vector{Plot} # the individual plots + plotter::PlottingPackage + p::Int # number of plots + n::Int # number of series + layout::SubPlotLayout +end \ No newline at end of file