started work on new FlexLayout, some reorg/cleaning
This commit is contained in:
parent
09d45aa64b
commit
7a5197df63
@ -14,6 +14,7 @@ export
|
|||||||
Subplot,
|
Subplot,
|
||||||
SubplotLayout,
|
SubplotLayout,
|
||||||
GridLayout,
|
GridLayout,
|
||||||
|
RowsLayout,
|
||||||
FlexLayout,
|
FlexLayout,
|
||||||
AVec,
|
AVec,
|
||||||
AMat,
|
AMat,
|
||||||
@ -26,7 +27,7 @@ export
|
|||||||
current,
|
current,
|
||||||
default,
|
default,
|
||||||
with,
|
with,
|
||||||
|
|
||||||
scatter,
|
scatter,
|
||||||
scatter!,
|
scatter!,
|
||||||
bar,
|
bar,
|
||||||
@ -138,6 +139,7 @@ include("plotter2.jl")
|
|||||||
include("args.jl")
|
include("args.jl")
|
||||||
include("plot.jl")
|
include("plot.jl")
|
||||||
include("subplot.jl")
|
include("subplot.jl")
|
||||||
|
include("layouts.jl")
|
||||||
include("recipes.jl")
|
include("recipes.jl")
|
||||||
include("animation.jl")
|
include("animation.jl")
|
||||||
include("output.jl")
|
include("output.jl")
|
||||||
|
|||||||
120
src/layouts.jl
Normal file
120
src/layouts.jl
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
|
# we're taking in a nested structure of some kind... parse it out and build a FlexLayout
|
||||||
|
function subplotlayout(mat::AbstractVecOrMat; widths = nothing, heights = nothing)
|
||||||
|
n = 0
|
||||||
|
nr, nc = size(mat)
|
||||||
|
grid = Array(IntOrFlex, nr, nc)
|
||||||
|
for i=1:nr, j=1:nc
|
||||||
|
v = mat[i,j]
|
||||||
|
|
||||||
|
if isa(v, Integer)
|
||||||
|
grid[i,j] = Int(v)
|
||||||
|
n += 1
|
||||||
|
|
||||||
|
elseif isa(v, Tuple)
|
||||||
|
warn("need to handle tuples somehow... (idx, sizepct)")
|
||||||
|
grid[i,j] = nothing
|
||||||
|
|
||||||
|
elseif v == nothing
|
||||||
|
grid[i,j] = nothing
|
||||||
|
|
||||||
|
elseif isa(v, AbstractVecOrMat)
|
||||||
|
grid[i,j] = layout(v)
|
||||||
|
n += grid[i,j].n
|
||||||
|
|
||||||
|
else
|
||||||
|
error("How do we process? $v")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if widths == nothing
|
||||||
|
widths = ones(nc) ./ nc
|
||||||
|
end
|
||||||
|
if heights == nothing
|
||||||
|
heights = ones(nr) ./ nr
|
||||||
|
end
|
||||||
|
|
||||||
|
FlexLayout(n, grid, widths, heights)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function subplotlayout(sz::Tuple{Int,Int})
|
||||||
|
GridLayout(sz...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function subplotlayout(rowcounts::AVec{Int})
|
||||||
|
RowsLayout(sum(rowcounts), rowcounts)
|
||||||
|
end
|
||||||
|
|
||||||
|
function subplotlayout(numplts::Int, nr::Int, nc::Int)
|
||||||
|
|
||||||
|
# figure out how many rows/columns we need
|
||||||
|
if nr == -1
|
||||||
|
if nc == -1
|
||||||
|
nr = round(Int, sqrt(numplts))
|
||||||
|
nc = ceil(Int, numplts / nr)
|
||||||
|
else
|
||||||
|
nr = ceil(Int, numplts / nc)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
nc = ceil(Int, numplts / nr)
|
||||||
|
end
|
||||||
|
|
||||||
|
# if it's a perfect rectangle, just create a grid
|
||||||
|
if numplts == nr * nc
|
||||||
|
return GridLayout(nr, nc)
|
||||||
|
end
|
||||||
|
|
||||||
|
# create the rowcounts vector
|
||||||
|
i = 0
|
||||||
|
rowcounts = Int[]
|
||||||
|
for r in 1:nr
|
||||||
|
cnt = min(nc, numplts - i)
|
||||||
|
push!(rowcounts, cnt)
|
||||||
|
i += cnt
|
||||||
|
end
|
||||||
|
|
||||||
|
RowsLayout(numplts, rowcounts)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Base.length(layout::RowsLayout) = layout.numplts
|
||||||
|
Base.start(layout::RowsLayout) = 1
|
||||||
|
Base.done(layout::RowsLayout, state) = state > length(layout)
|
||||||
|
function Base.next(layout::RowsLayout, state)
|
||||||
|
r = 1
|
||||||
|
c = 0
|
||||||
|
for i = 1:state
|
||||||
|
c += 1
|
||||||
|
if c > layout.rowcounts[r]
|
||||||
|
r += 1
|
||||||
|
c = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
(r,c), state + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
nrows(layout::RowsLayout) = length(layout.rowcounts)
|
||||||
|
ncols(layout::RowsLayout, row::Int) = row < 1 ? 0 : (row > nrows(layout) ? 0 : layout.rowcounts[row])
|
||||||
|
|
||||||
|
# get the plot index given row and column
|
||||||
|
Base.getindex(layout::RowsLayout, r::Int, c::Int) = sum(layout.rowcounts[1:r-1]) + c
|
||||||
|
|
||||||
|
Base.length(layout::GridLayout) = layout.nr * layout.nc
|
||||||
|
Base.start(layout::GridLayout) = 1
|
||||||
|
Base.done(layout::GridLayout, state) = state > length(layout)
|
||||||
|
function Base.next(layout::GridLayout, state)
|
||||||
|
r = div(state-1, layout.nc) + 1
|
||||||
|
c = mod1(state, layout.nc)
|
||||||
|
(r,c), state + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
nrows(layout::GridLayout) = layout.nr
|
||||||
|
ncols(layout::GridLayout) = layout.nc
|
||||||
|
ncols(layout::GridLayout, row::Int) = layout.nc
|
||||||
|
|
||||||
|
# get the plot index given row and column
|
||||||
|
Base.getindex(layout::GridLayout, r::Int, c::Int) = (r-1) * layout.nc + c
|
||||||
@ -1,83 +1,4 @@
|
|||||||
|
|
||||||
function subplotlayout(sz::@compat(Tuple{Int,Int}))
|
|
||||||
GridLayout(sz...)
|
|
||||||
end
|
|
||||||
|
|
||||||
function subplotlayout(rowcounts::AVec{Int})
|
|
||||||
FlexLayout(sum(rowcounts), rowcounts)
|
|
||||||
end
|
|
||||||
|
|
||||||
function subplotlayout(numplts::Int, nr::Int, nc::Int)
|
|
||||||
|
|
||||||
# figure out how many rows/columns we need
|
|
||||||
if nr == -1
|
|
||||||
if nc == -1
|
|
||||||
nr = round(Int, sqrt(numplts))
|
|
||||||
nc = ceil(Int, numplts / nr)
|
|
||||||
else
|
|
||||||
nr = ceil(Int, numplts / nc)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
nc = ceil(Int, numplts / nr)
|
|
||||||
end
|
|
||||||
|
|
||||||
# if it's a perfect rectangle, just create a grid
|
|
||||||
if numplts == nr * nc
|
|
||||||
return GridLayout(nr, nc)
|
|
||||||
end
|
|
||||||
|
|
||||||
# create the rowcounts vector
|
|
||||||
i = 0
|
|
||||||
rowcounts = Int[]
|
|
||||||
for r in 1:nr
|
|
||||||
cnt = min(nc, numplts - i)
|
|
||||||
push!(rowcounts, cnt)
|
|
||||||
i += cnt
|
|
||||||
end
|
|
||||||
|
|
||||||
FlexLayout(numplts, rowcounts)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Base.length(layout::FlexLayout) = layout.numplts
|
|
||||||
Base.start(layout::FlexLayout) = 1
|
|
||||||
Base.done(layout::FlexLayout, state) = state > length(layout)
|
|
||||||
function Base.next(layout::FlexLayout, state)
|
|
||||||
r = 1
|
|
||||||
c = 0
|
|
||||||
for i = 1:state
|
|
||||||
c += 1
|
|
||||||
if c > layout.rowcounts[r]
|
|
||||||
r += 1
|
|
||||||
c = 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
(r,c), state + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
nrows(layout::FlexLayout) = length(layout.rowcounts)
|
|
||||||
ncols(layout::FlexLayout, row::Int) = row < 1 ? 0 : (row > nrows(layout) ? 0 : layout.rowcounts[row])
|
|
||||||
|
|
||||||
# get the plot index given row and column
|
|
||||||
Base.getindex(layout::FlexLayout, r::Int, c::Int) = sum(layout.rowcounts[1:r-1]) + c
|
|
||||||
|
|
||||||
Base.length(layout::GridLayout) = layout.nr * layout.nc
|
|
||||||
Base.start(layout::GridLayout) = 1
|
|
||||||
Base.done(layout::GridLayout, state) = state > length(layout)
|
|
||||||
function Base.next(layout::GridLayout, state)
|
|
||||||
r = div(state-1, layout.nc) + 1
|
|
||||||
c = mod1(state, layout.nc)
|
|
||||||
(r,c), state + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
nrows(layout::GridLayout) = layout.nr
|
|
||||||
ncols(layout::GridLayout) = layout.nc
|
|
||||||
ncols(layout::GridLayout, row::Int) = layout.nc
|
|
||||||
|
|
||||||
# get the plot index given row and column
|
|
||||||
Base.getindex(layout::GridLayout, r::Int, c::Int) = (r-1) * layout.nc + c
|
|
||||||
|
|
||||||
Base.getindex(subplt::Subplot, args...) = subplt.plts[subplt.layout[args...]]
|
Base.getindex(subplt::Subplot, args...) = subplt.plts[subplt.layout[args...]]
|
||||||
|
|
||||||
# handle "linking" the subplot axes together
|
# handle "linking" the subplot axes together
|
||||||
@ -308,7 +229,7 @@ function subplot!(subplt::Subplot, args...; kw...)
|
|||||||
|
|
||||||
# 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
|
||||||
# this is because some backends need to set up the subplots and then plot,
|
# this is because some backends need to set up the subplots and then plot,
|
||||||
# and others need to do it the other way around
|
# and others need to do it the other way around
|
||||||
if !subplt.initialized
|
if !subplt.initialized
|
||||||
subplt.initialized = _create_subplot(subplt, true)
|
subplt.initialized = _create_subplot(subplt, true)
|
||||||
@ -343,7 +264,7 @@ function subplot!(subplt::Subplot, args...; kw...)
|
|||||||
end
|
end
|
||||||
dumpdict(di, "subplot! kwList $i")
|
dumpdict(di, "subplot! kwList $i")
|
||||||
dumpdict(plt.plotargs, "plt.plotargs before plotting")
|
dumpdict(plt.plotargs, "plt.plotargs before plotting")
|
||||||
|
|
||||||
_add_series_subplot(plt; di...)
|
_add_series_subplot(plt; di...)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -366,7 +287,7 @@ function _add_series_subplot(plt::Plot, args...; kw...)
|
|||||||
setTicksFromStringVector(d, d, :y, :yticks)
|
setTicksFromStringVector(d, d, :y, :yticks)
|
||||||
|
|
||||||
_add_series(plt.backend, plt; d...)
|
_add_series(plt.backend, plt; d...)
|
||||||
|
|
||||||
_add_annotations(plt, d)
|
_add_annotations(plt, d)
|
||||||
warnOnUnsupportedScales(plt.backend, d)
|
warnOnUnsupportedScales(plt.backend, d)
|
||||||
end
|
end
|
||||||
|
|||||||
75
src/types.jl
75
src/types.jl
@ -3,47 +3,74 @@ typealias AVec AbstractVector
|
|||||||
typealias AMat AbstractMatrix
|
typealias AMat AbstractMatrix
|
||||||
|
|
||||||
immutable PlotsDisplay <: Display end
|
immutable PlotsDisplay <: Display end
|
||||||
|
|
||||||
abstract PlottingPackage
|
abstract PlottingPackage
|
||||||
abstract PlottingObject{T<:PlottingPackage}
|
abstract PlottingObject{T<:PlottingPackage}
|
||||||
|
|
||||||
type Plot{T<:PlottingPackage} <: PlottingObject{T}
|
# -----------------------------------------------------------
|
||||||
o # the underlying object
|
# Plot
|
||||||
backend::T
|
# -----------------------------------------------------------
|
||||||
n::Int # number of series
|
|
||||||
|
|
||||||
# store these just in case
|
type Plot{T<:PlottingPackage} <: PlottingObject{T}
|
||||||
plotargs::Dict
|
o # the backend's plot object
|
||||||
seriesargs::Vector{Dict} # args for each series
|
backend::T # the backend type
|
||||||
|
n::Int # number of series
|
||||||
|
plotargs::Dict # arguments for the whole plot
|
||||||
|
seriesargs::Vector{Dict} # arguments for each series
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
# Layouts
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
abstract SubplotLayout
|
abstract SubplotLayout
|
||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
|
"Simple grid, indices are row-major."
|
||||||
immutable GridLayout <: SubplotLayout
|
immutable GridLayout <: SubplotLayout
|
||||||
nr::Int
|
nr::Int
|
||||||
nc::Int
|
nc::Int
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
|
"Number of plots per row"
|
||||||
|
immutable RowsLayout <: SubplotLayout
|
||||||
|
numplts::Int
|
||||||
|
rowcounts::AbstractVector{Int}
|
||||||
|
end
|
||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
|
"Flexible, nested layout with optional size percentages."
|
||||||
immutable FlexLayout <: SubplotLayout
|
immutable FlexLayout <: SubplotLayout
|
||||||
numplts::Int
|
n::Int
|
||||||
rowcounts::AbstractVector{Int}
|
grid::Matrix # Nested layouts. Each position
|
||||||
|
# can be a plot index or another FlexLayout
|
||||||
|
widths::Vector{Float64}
|
||||||
|
heights::Vector{Float64}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
typealias IntOrFlex Union{Int,FlexLayout}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
# Subplot
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
|
||||||
type Subplot{T<:PlottingPackage, L<:SubplotLayout} <: PlottingObject{T}
|
type Subplot{T<:PlottingPackage, L<:SubplotLayout} <: PlottingObject{T}
|
||||||
o # the underlying object
|
o # the underlying object
|
||||||
plts::Vector{Plot{T}} # the individual plots
|
plts::Vector{Plot{T}} # the individual plots
|
||||||
backend::T
|
backend::T
|
||||||
p::Int # number of plots
|
p::Int # number of plots
|
||||||
n::Int # number of series
|
n::Int # number of series
|
||||||
layout::L
|
layout::L
|
||||||
# plotargs::Vector{Dict}
|
# plotargs::Vector{Dict}
|
||||||
plotargs::Dict
|
plotargs::Dict
|
||||||
initialized::Bool
|
initialized::Bool
|
||||||
linkx::Bool
|
linkx::Bool
|
||||||
linky::Bool
|
linky::Bool
|
||||||
linkfunc::Function # maps (row,column) -> (BoolOrNothing, BoolOrNothing)... if xlink/ylink are nothing, then use subplt.linkx/y
|
linkfunc::Function # maps (row,column) -> (BoolOrNothing, BoolOrNothing)... if xlink/ylink are nothing, then use subplt.linkx/y
|
||||||
end
|
end
|
||||||
|
|
||||||
# -----------------------------------------------------------------------
|
# -----------------------------------------------------------------------
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user