working on subplot

This commit is contained in:
Thomas Breloff 2015-09-11 14:01:00 -04:00
parent 75dbe9a46e
commit c9d2119ba5
3 changed files with 68 additions and 33 deletions

View File

@ -82,7 +82,8 @@ include("plot.jl")
include("subplot.jl")
# const LINE_TYPES = (:line, :step, :stepinverted, :sticks, :dots, :none, :heatmap, :hist, :bar)
# ---------------------------------------------------------
scatter(args...; kw...) = plot(args...; kw..., linetype = :none, marker = :hexagon)
scatter!(args...; kw...) = plot!(args...; kw..., linetype = :none, marker = :hexagon)
bar(args...; kw...) = plot(args...; kw..., linetype = :bar)
@ -95,13 +96,6 @@ heatmap!(args...; kw...) = plot!(args...; kw..., linetype = :heatmap)
# ---------------------------------------------------------
# # TODO: how do we handle NA values in dataframes?
# function plot!(plt::Plot, df::DataFrame; kw...) # one line per DataFrame column, labels == names(df)
# end
# function plot!(plt::Plot, df::DataFrame, columns; kw...) # one line per column, but on a subset of column names
# end
savepng(args...; kw...) = savepng(currentPlot(), args...; kw...)
savepng(plt::Plot, args...; kw...) = savepng(plt.plotter, plt, args...; kw...)

View File

@ -241,6 +241,8 @@ function createKWargsList(plt::PlottingObject, n::Integer; kw...)
ret
end
# TODO: handle DataFrames (might have NAs!)
# -------------------------
# most calls should flow through here now... we create a Dict with the keyword args for each series, and plot them

View File

@ -1,31 +1,51 @@
abstract SubPlotLayout
type AutoGridLayout
maxplts::Int
maxrows::Int
maxcols::Int
type SubPlotLayout
numplts::Int
rowcounts::AbstractVector{Int}
end
# create a grid structure that optimally fits in numplts, optionally fixing the numrows/numcols
function AutoGridLayout(numplts::Int; numrows::Int = -1, numcols::Int = -1)
# create a layout directly
SubPlotLayout(rowcounts::AbstractVector{Int}) = SubPlotLayout(sum(rowcounts), rowcounts)
# create a layout given counts... numrows/numcols == -1 implies we figure out a good number automatically
function SubPlotLayout(numplts::Int, numrows::Int, numcols::Int)
# figure out how many rows/columns we need
if numrows == -1
if numcols == -1
numrows = round(Int, sqrt(numplts))
numcols = ceil(Int, numplts / numrows)
else
numrows = ceil(Int, numplts / numcols)
end
else
numcols = ceil(Int, numplts / numrows)
end
# create the rowcounts vector
i = 0
rowcounts = Int[]
for r in 1:numrows
cnt = min(numcols, numplts - i)
push!(rowcounts, cnt)
i += cnt
end
SubPlotLayout(numplts, rowcounts)
end
Base.length(layout::SubPlotLayout) = layout.numplts
# ------------------------------------------------------------
doc"""
y = rand(100,3)
subplot(y; layout=(2,2), kw...) # creates 3 lines going into 3 separate plots, laid out on a 2x2 grid (last row is filled with plot #3)
subplot(y; layout=(1,3), kw...) # again 3 plots, all in the same row
subplot(y; layout=[1,[2,3]]) # pass a nested Array to fully specify the layout. here the first plot will take up the first row,
# and the others will share the second row
"""
type SubPlot <: PlottingObject
plts::Vector{Plot} # the underlying object
o # the underlying object
plts::Vector{Plot} # the individual plots
plotter::PlottingPackage
p::Int # number of plots
n::Int # number of series
p::Int # number of plots
n::Int # number of series
layout::SubPlotLayout
end
@ -38,18 +58,37 @@ getplot(subplt::SubPlot, i::Int) = subplt.plts[mod1(i, 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)
"""
function subplot(args...; kw...)
subplt = SubPlot(Plot[], plotter(), 0, 0)
d = Dict(kw)
# figure out the layouts
if !haskey(d, :layout) || d[:layout] == :auto
# do an automatic grid layout
# figure out the layout
if !haskey(d, :layout)
layout = FixedLayout(d[:layout])
else
layout = d[:layout]
if !haskey(d, :n)
error("You must specify either layout or n when creating a subplot: ", d)
end
layout = AutoGridLayout(d[:n], get(d, :numrows, -1), get(d, :numcols, -1))
end
# initialize the individual plots
pkg = plotter()
kw0 = getPlotKeywordArgs(kw, 1, 0)
plts = Plot[plot(pkg; kw0..., show=false) for i in 1:length(layout)]
# create the underlying object (each backend will do this differently)
o = buildSubplotObject(plts, pkg, layout)
# create the object and do the plotting
subplt = SubPlot(o, plts, pkg, length(layout), 0, layout)
subplot!(subplt, args...; kw...)
end