diff --git a/src/Plots.jl b/src/Plots.jl
index cd4a052a..267889f9 100644
--- a/src/Plots.jl
+++ b/src/Plots.jl
@@ -14,10 +14,11 @@ export
AbstractPlot,
Plot,
Subplot,
- SubplotLayout,
+ AbstractLayout,
GridLayout,
- RowsLayout,
- FlexLayout,
+ EmptyLayout,
+ # RowsLayout,
+ # FlexLayout,
AVec,
AMat,
KW,
diff --git a/src/args.jl b/src/args.jl
index 2372a2ea..ca649a1a 100644
--- a/src/args.jl
+++ b/src/args.jl
@@ -156,6 +156,7 @@ _seriesDefaults[:weights] = nothing # optional weights for histograms
_seriesDefaults[:contours] = false # add contours to 3d surface and wireframe plots
_seriesDefaults[:match_dimensions] = false # do rows match x (true) or y (false) for heatmap/image/spy? see issue 196
# this ONLY effects whether or not the z-matrix is transposed for a heatmap display!
+_seriesDefaults[:subplot_index] = :auto
const _plotDefaults = KW()
diff --git a/src/backends.jl b/src/backends.jl
index 956861f5..acc87b80 100644
--- a/src/backends.jl
+++ b/src/backends.jl
@@ -48,8 +48,8 @@ include("backends/web.jl")
plot(pkg::AbstractBackend; kw...) = error("plot($pkg; kw...) is not implemented")
plot!(pkg::AbstractBackend, plt::Plot; kw...) = error("plot!($pkg, plt; kw...) is not implemented")
_update_plot(pkg::AbstractBackend, plt::Plot, d::KW) = error("_update_plot($pkg, plt, d) is not implemented")
-subplot(pkg::AbstractBackend; kw...) = error("subplot($pkg; kw...) is not implemented")
-subplot!(pkg::AbstractBackend, subplt::Subplot; kw...) = error("subplot!($pkg, subplt; kw...) is not implemented")
+# subplot(pkg::AbstractBackend; kw...) = error("subplot($pkg; kw...) is not implemented")
+# subplot!(pkg::AbstractBackend, subplt::Subplot; kw...) = error("subplot!($pkg, subplt; kw...) is not implemented")
# don't do anything as a default
_create_backend_figure(plt::Plot) = nothing
diff --git a/src/backends/bokeh.jl b/src/backends/bokeh.jl
index f842b355..86ecd847 100644
--- a/src/backends/bokeh.jl
+++ b/src/backends/bokeh.jl
@@ -209,10 +209,10 @@ end
# ----------------------------------------------------------------
-function _create_subplot(subplt::Subplot{BokehBackend}, isbefore::Bool)
- # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
-
-end
+# function _create_subplot(subplt::Subplot{BokehBackend}, isbefore::Bool)
+# # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
+#
+# end
function _expand_limits(lims, plt::Plot{BokehBackend}, isx::Bool)
@@ -234,6 +234,6 @@ function Base.display(::PlotsDisplay, plt::Plot{BokehBackend})
Bokeh.showplot(plt.o)
end
-function Base.display(::PlotsDisplay, plt::Subplot{BokehBackend})
- # TODO: display/show the subplot
-end
+# function Base.display(::PlotsDisplay, plt::Subplot{BokehBackend})
+# # TODO: display/show the subplot
+# end
diff --git a/src/backends/gadfly.jl b/src/backends/gadfly.jl
index 67d817c4..2c37516a 100644
--- a/src/backends/gadfly.jl
+++ b/src/backends/gadfly.jl
@@ -626,12 +626,12 @@ end
# ----------------------------------------------------------------
-# create the underlying object (each backend will do this differently)
-function _create_subplot(subplt::Subplot{GadflyBackend}, isbefore::Bool)
- isbefore && return false # wait until after plotting to create the subplots
- subplt.o = nothing
- true
-end
+# # create the underlying object (each backend will do this differently)
+# function _create_subplot(subplt::Subplot{GadflyBackend}, isbefore::Bool)
+# isbefore && return false # wait until after plotting to create the subplots
+# subplt.o = nothing
+# true
+# end
function _remove_axis(plt::Plot{GadflyBackend}, isx::Bool)
@@ -651,31 +651,31 @@ end
getGadflyContext(plt::Plot{GadflyBackend}) = plt.o
-getGadflyContext(subplt::Subplot{GadflyBackend}) = buildGadflySubplotContext(subplt)
+# getGadflyContext(subplt::Subplot{GadflyBackend}) = buildGadflySubplotContext(subplt)
-# create my Compose.Context grid by hstacking and vstacking the Gadfly.Plot objects
-function buildGadflySubplotContext(subplt::Subplot)
- rows = Any[]
- row = Any[]
- for (i,(r,c)) in enumerate(subplt.layout)
-
- # add the Plot object to the row
- push!(row, getGadflyContext(subplt.plts[i]))
-
- # add the row
- if c == ncols(subplt.layout, r)
- push!(rows, Gadfly.hstack(row...))
- row = Any[]
- end
- end
-
- # stack the rows
- Gadfly.vstack(rows...)
-end
+# # create my Compose.Context grid by hstacking and vstacking the Gadfly.Plot objects
+# function buildGadflySubplotContext(subplt::Subplot)
+# rows = Any[]
+# row = Any[]
+# for (i,(r,c)) in enumerate(subplt.layout)
+#
+# # add the Plot object to the row
+# push!(row, getGadflyContext(subplt.plts[i]))
+#
+# # add the row
+# if c == ncols(subplt.layout, r)
+# push!(rows, Gadfly.hstack(row...))
+# row = Any[]
+# end
+# end
+#
+# # stack the rows
+# Gadfly.vstack(rows...)
+# end
setGadflyDisplaySize(w,h) = Compose.set_default_graphic_size(w * Compose.px, h * Compose.px)
setGadflyDisplaySize(plt::Plot) = setGadflyDisplaySize(plt.plotargs[:size]...)
-setGadflyDisplaySize(subplt::Subplot) = setGadflyDisplaySize(getplotargs(subplt, 1)[:size]...)
+# setGadflyDisplaySize(subplt::Subplot) = setGadflyDisplaySize(getplotargs(subplt, 1)[:size]...)
# -------------------------------------------------------------------------
@@ -708,39 +708,39 @@ function Base.display(::PlotsDisplay, plt::Plot{GadflyBackend})
end
-function Base.display(::PlotsDisplay, subplt::Subplot{GadflyBackend})
- setGadflyDisplaySize(getplotargs(subplt,1)[:size]...)
- ctx = buildGadflySubplotContext(subplt)
-
- # taken from Gadfly since I couldn't figure out how to do it directly
-
- filename = string(Gadfly.tempname(), ".html")
- output = open(filename, "w")
-
- plot_output = IOBuffer()
- Gadfly.draw(Gadfly.SVGJS(plot_output, Compose.default_graphic_width,
- Compose.default_graphic_height, false), ctx)
- plotsvg = takebuf_string(plot_output)
-
- write(output,
- """
-
-
-
- Gadfly Plot
-
-
-
-
-
- $(plotsvg)
-
-
- """)
- close(output)
- Gadfly.open_file(filename)
-end
+# function Base.display(::PlotsDisplay, subplt::Subplot{GadflyBackend})
+# setGadflyDisplaySize(getplotargs(subplt,1)[:size]...)
+# ctx = buildGadflySubplotContext(subplt)
+#
+# # taken from Gadfly since I couldn't figure out how to do it directly
+#
+# filename = string(Gadfly.tempname(), ".html")
+# output = open(filename, "w")
+#
+# plot_output = IOBuffer()
+# Gadfly.draw(Gadfly.SVGJS(plot_output, Compose.default_graphic_width,
+# Compose.default_graphic_height, false), ctx)
+# plotsvg = takebuf_string(plot_output)
+#
+# write(output,
+# """
+#
+#
+#
+# Gadfly Plot
+#
+#
+#
+#
+#
+# $(plotsvg)
+#
+#
+# """)
+# close(output)
+# Gadfly.open_file(filename)
+# end
diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl
index 150f1fbf..a8b40243 100644
--- a/src/backends/glvisualize.jl
+++ b/src/backends/glvisualize.jl
@@ -143,9 +143,9 @@ end
# ----------------------------------------------------------------
-function _create_subplot(subplt::Subplot{GLVisualizeBackend})
- # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
-end
+# function _create_subplot(subplt::Subplot{GLVisualizeBackend})
+# # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
+# end
function _expand_limits(lims, plt::Plot{GLVisualizeBackend}, isx::Bool)
# TODO: call expand limits for each plot data
@@ -169,6 +169,6 @@ function Base.display(::PlotsDisplay, plt::Plot{GLVisualizeBackend})
# wouldn't actually need to do anything
end
-function Base.display(::PlotsDisplay, plt::Subplot{GLVisualizeBackend})
- # TODO: display/show the subplot
-end
+# function Base.display(::PlotsDisplay, plt::Subplot{GLVisualizeBackend})
+# # TODO: display/show the subplot
+# end
diff --git a/src/backends/gr.jl b/src/backends/gr.jl
index 767ba3f2..304bc7f7 100644
--- a/src/backends/gr.jl
+++ b/src/backends/gr.jl
@@ -832,21 +832,21 @@ function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
update && GR.updatews()
end
-function gr_display(subplt::Subplot{GRBackend})
- clear = true
- update = false
- l = enumerate(subplt.layout)
- nr = nrows(subplt.layout)
- for (i, (r, c)) in l
- nc = ncols(subplt.layout, r)
- if i == length(l)
- update = true
- end
- subplot = [(c-1)/nc, c/nc, 1-r/nr, 1-(r-1)/nr]
- gr_display(subplt.plts[i], clear, update, subplot)
- clear = false
- end
-end
+# function gr_display(subplt::Subplot{GRBackend})
+# clear = true
+# update = false
+# l = enumerate(subplt.layout)
+# nr = nrows(subplt.layout)
+# for (i, (r, c)) in l
+# nc = ncols(subplt.layout, r)
+# if i == length(l)
+# update = true
+# end
+# subplot = [(c-1)/nc, c/nc, 1-r/nr, 1-(r-1)/nr]
+# gr_display(subplt.plts[i], clear, update, subplot)
+# clear = false
+# end
+# end
# function _create_plot(pkg::GRBackend, d::KW)
# Plot(nothing, pkg, 0, d, KW[])
@@ -948,7 +948,7 @@ function Base.display(::PlotsDisplay, plt::Plot{GRBackend})
gr_display(plt)
end
-function Base.display(::PlotsDisplay, plt::Subplot{GRBackend})
- gr_display(plt)
- true
-end
+# function Base.display(::PlotsDisplay, plt::Subplot{GRBackend})
+# gr_display(plt)
+# true
+# end
diff --git a/src/backends/immerse.jl b/src/backends/immerse.jl
index 733c1b79..a974448b 100644
--- a/src/backends/immerse.jl
+++ b/src/backends/immerse.jl
@@ -88,51 +88,51 @@ end
# ----------------------------------------------------------------
-function _create_subplot(subplt::Subplot{ImmerseBackend}, isbefore::Bool)
- return false
- # isbefore && return false
-end
-
-function showSubplotObject(subplt::Subplot{ImmerseBackend})
- # create the Gtk window with vertical box vsep
- d = getplotargs(subplt,1)
- w,h = d[:size]
- vsep = Gtk.GtkBoxLeaf(:v)
- win = Gtk.GtkWindowLeaf(vsep, d[:windowtitle], w, h)
-
- figindices = []
- row = Gtk.GtkBoxLeaf(:h)
- push!(vsep, row)
- for (i,(r,c)) in enumerate(subplt.layout)
- plt = subplt.plts[i]
-
- # get the components... box is the main plot GtkBox, and canvas is the GtkCanvas where it's plotted
- box, toolbar, canvas = Immerse.createPlotGuiComponents()
-
- # add the plot's box to the row
- push!(row, box)
-
- # create the figure and store the index returned for destruction later
- figidx = Immerse.figure(canvas)
- push!(figindices, figidx)
-
- fig = Immerse.figure(figidx)
- plt.o = (fig, plt.o[2])
-
- # add the row
- if c == ncols(subplt.layout, r)
- row = Gtk.GtkBoxLeaf(:h)
- push!(vsep, row)
- end
-
- end
-
- # destructor... clean up plots
- Gtk.on_signal_destroy((x...) -> ([Immerse.dropfig(Immerse._display,i) for i in figindices]; subplt.o = nothing), win)
-
- subplt.o = win
- true
-end
+# function _create_subplot(subplt::Subplot{ImmerseBackend}, isbefore::Bool)
+# return false
+# # isbefore && return false
+# end
+#
+# function showSubplotObject(subplt::Subplot{ImmerseBackend})
+# # create the Gtk window with vertical box vsep
+# d = getplotargs(subplt,1)
+# w,h = d[:size]
+# vsep = Gtk.GtkBoxLeaf(:v)
+# win = Gtk.GtkWindowLeaf(vsep, d[:windowtitle], w, h)
+#
+# figindices = []
+# row = Gtk.GtkBoxLeaf(:h)
+# push!(vsep, row)
+# for (i,(r,c)) in enumerate(subplt.layout)
+# plt = subplt.plts[i]
+#
+# # get the components... box is the main plot GtkBox, and canvas is the GtkCanvas where it's plotted
+# box, toolbar, canvas = Immerse.createPlotGuiComponents()
+#
+# # add the plot's box to the row
+# push!(row, box)
+#
+# # create the figure and store the index returned for destruction later
+# figidx = Immerse.figure(canvas)
+# push!(figindices, figidx)
+#
+# fig = Immerse.figure(figidx)
+# plt.o = (fig, plt.o[2])
+#
+# # add the row
+# if c == ncols(subplt.layout, r)
+# row = Gtk.GtkBoxLeaf(:h)
+# push!(vsep, row)
+# end
+#
+# end
+#
+# # destructor... clean up plots
+# Gtk.on_signal_destroy((x...) -> ([Immerse.dropfig(Immerse._display,i) for i in figindices]; subplt.o = nothing), win)
+#
+# subplt.o = win
+# true
+# end
function _remove_axis(plt::Plot{ImmerseBackend}, isx::Bool)
@@ -151,7 +151,7 @@ end
# ----------------------------------------------------------------
getGadflyContext(plt::Plot{ImmerseBackend}) = plt.o[2]
-getGadflyContext(subplt::Subplot{ImmerseBackend}) = buildGadflySubplotContext(subplt)
+# getGadflyContext(subplt::Subplot{ImmerseBackend}) = buildGadflySubplotContext(subplt)
function Base.display(::PlotsDisplay, plt::Plot{ImmerseBackend})
@@ -168,20 +168,20 @@ function Base.display(::PlotsDisplay, plt::Plot{ImmerseBackend})
end
-function Base.display(::PlotsDisplay, subplt::Subplot{ImmerseBackend})
-
- # if we haven't created the window yet, do it
- if subplt.o == nothing
- showSubplotObject(subplt)
- end
-
- # display the plots by creating a fresh Immerse.Figure object from the GtkCanvas and Gadfly.Plot
- for plt in subplt.plts
- fig, gplt = plt.o
- Immerse.figure(fig.figno; displayfig = false)
- display(gplt)
- end
-
- # o is the window... show it
- showall(subplt.o)
-end
+# function Base.display(::PlotsDisplay, subplt::Subplot{ImmerseBackend})
+#
+# # if we haven't created the window yet, do it
+# if subplt.o == nothing
+# showSubplotObject(subplt)
+# end
+#
+# # display the plots by creating a fresh Immerse.Figure object from the GtkCanvas and Gadfly.Plot
+# for plt in subplt.plts
+# fig, gplt = plt.o
+# Immerse.figure(fig.figno; displayfig = false)
+# display(gplt)
+# end
+#
+# # o is the window... show it
+# showall(subplt.o)
+# end
diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl
index bf2adcd5..54ca1550 100644
--- a/src/backends/plotly.jl
+++ b/src/backends/plotly.jl
@@ -135,10 +135,10 @@ end
# ----------------------------------------------------------------
-function _create_subplot(subplt::Subplot{PlotlyBackend}, isbefore::Bool)
- # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
- true
-end
+# function _create_subplot(subplt::Subplot{PlotlyBackend}, isbefore::Bool)
+# # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
+# true
+# end
function _expand_limits(lims, plt::Plot{PlotlyBackend}, isx::Bool)
# TODO: call expand limits for each plot data
@@ -516,15 +516,15 @@ function get_series_json(plt::Plot{PlotlyBackend})
JSON.json(map(d -> plotly_series(d, plt.plotargs), plt.seriesargs))
end
-function get_series_json(subplt::Subplot{PlotlyBackend})
- ds = KW[]
- for (i,plt) in enumerate(subplt.plts)
- for d in plt.seriesargs
- push!(ds, plotly_series(d, plt.plotargs, plot_index = i))
- end
- end
- JSON.json(ds)
-end
+# function get_series_json(subplt::Subplot{PlotlyBackend})
+# ds = KW[]
+# for (i,plt) in enumerate(subplt.plts)
+# for d in plt.seriesargs
+# push!(ds, plotly_series(d, plt.plotargs, plot_index = i))
+# end
+# end
+# JSON.json(ds)
+# end
# ----------------------------------------------------------------
@@ -557,29 +557,29 @@ function js_body(plt::Plot{PlotlyBackend}, uuid)
end
-function html_body(subplt::Subplot{PlotlyBackend})
- w, h = subplt.plts[1].plotargs[:size]
- html = [""]
- nr = nrows(subplt.layout)
- ph = h / nr
-
- for r in 1:nr
- push!(html, "
")
-
- nc = ncols(subplt.layout, r)
- pw = w / nc
-
- for c in 1:nc
- plt = subplt[r,c]
- push!(html, html_body(plt, "float:left; width:$(pw)px; height:$(ph)px;"))
- end
-
- push!(html, "
")
- end
- push!(html, "
")
-
- join(html)
-end
+# function html_body(subplt::Subplot{PlotlyBackend})
+# w, h = subplt.plts[1].plotargs[:size]
+# html = [""]
+# nr = nrows(subplt.layout)
+# ph = h / nr
+#
+# for r in 1:nr
+# push!(html, "
")
+#
+# nc = ncols(subplt.layout, r)
+# pw = w / nc
+#
+# for c in 1:nc
+# plt = subplt[r,c]
+# push!(html, html_body(plt, "float:left; width:$(pw)px; height:$(ph)px;"))
+# end
+#
+# push!(html, "
")
+# end
+# push!(html, "
")
+#
+# join(html)
+# end
# ----------------------------------------------------------------
diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl
index f57e05d9..6adc70e2 100644
--- a/src/backends/plotlyjs.jl
+++ b/src/backends/plotlyjs.jl
@@ -178,10 +178,10 @@ end
# ----------------------------------------------------------------
-function _create_subplot(subplt::Subplot{PlotlyJSBackend}, isbefore::Bool)
- # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
- true
-end
+# function _create_subplot(subplt::Subplot{PlotlyJSBackend}, isbefore::Bool)
+# # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
+# true
+# end
function _expand_limits(lims, plt::Plot{PlotlyJSBackend}, isx::Bool)
# TODO: call expand limits for each plot data
@@ -206,6 +206,6 @@ function Base.display(::PlotsDisplay, plt::Plot{PlotlyJSBackend})
display(plt.o)
end
-function Base.display(::PlotsDisplay, plt::Subplot{PlotlyJSBackend})
- error()
-end
+# function Base.display(::PlotsDisplay, plt::Subplot{PlotlyJSBackend})
+# error()
+# end
diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl
index 13981157..7e5c0909 100644
--- a/src/backends/pyplot.jl
+++ b/src/backends/pyplot.jl
@@ -222,40 +222,62 @@ end
# ---------------------------------------------------------------------------
-type PyPlotAxisWrapper
- ax
- rightax
- fig
- kwargs # for add_subplot
-end
-
-getfig(wrap::PyPlotAxisWrapper) = wrap.fig
-
-
-
-# get a reference to the correct axis
-function getLeftAxis(wrap::PyPlotAxisWrapper)
- if wrap.ax == nothing
- axes = wrap.fig.o[:axes]
- if isempty(axes)
- return wrap.fig.o[:add_subplot](111; wrap.kwargs...)
- end
- axes[1]
- else
- wrap.ax
+function getAxis(plt::Plot{PyPlotBackend}, subplot::Subplot = plt.subplots[1])
+ if subplot.o == nothing
+ @show subplot
+ fig = plt.o
+ @show plt
+ # if fig == nothing
+ # fig =
+ # TODO: actual coords?
+ # NOTE: might want to use ax[:get_tightbbox](ax[:get_renderer_cache]()) to calc size of guides?
+ # NOTE: can set subplot location later with ax[:set_position]([left, bottom, width, height])
+ left, bottom, width, height = 0.3, 0.3, 0.5, 0.5
+ ax = fig[:add_axes]([left, bottom, width, height])
+ subplot.o = ax
end
+ subplot.o
end
-function getRightAxis(wrap::PyPlotAxisWrapper)
- if wrap.rightax == nothing
- wrap.rightax = getLeftAxis(wrap)[:twinx]()
- end
- wrap.rightax
-end
+getLeftAxis(plt::Plot{PyPlotBackend}, subplot::Subplot = plt.subplots[1]) = getAxis(plt, subplot)
+getfig(o) = o
-getLeftAxis(plt::Plot{PyPlotBackend}) = getLeftAxis(plt.o)
-getRightAxis(plt::Plot{PyPlotBackend}) = getRightAxis(plt.o)
-getAxis(plt::Plot{PyPlotBackend}, axis::Symbol) = (axis == :right ? getRightAxis : getLeftAxis)(plt)
+# ---------------------------------------------------------------------------
+
+# type PyPlotAxisWrapper
+# ax
+# rightax
+# fig
+# kwargs # for add_subplot
+# end
+#
+# getfig(wrap::PyPlotAxisWrapper) = wrap.fig
+#
+#
+#
+# # get a reference to the correct axis
+# function getLeftAxis(wrap::PyPlotAxisWrapper)
+# if wrap.ax == nothing
+# axes = wrap.fig.o[:axes]
+# if isempty(axes)
+# return wrap.fig.o[:add_subplot](111; wrap.kwargs...)
+# end
+# axes[1]
+# else
+# wrap.ax
+# end
+# end
+#
+# function getRightAxis(wrap::PyPlotAxisWrapper)
+# if wrap.rightax == nothing
+# wrap.rightax = getLeftAxis(wrap)[:twinx]()
+# end
+# wrap.rightax
+# end
+#
+# getLeftAxis(plt::Plot{PyPlotBackend}) = getLeftAxis(plt.o)
+# getRightAxis(plt::Plot{PyPlotBackend}) = getRightAxis(plt.o)
+# # getAxis(plt::Plot{PyPlotBackend}, axis::Symbol) = (axis == :right ? getRightAxis : getLeftAxis)(plt)
function handleSmooth(plt::Plot{PyPlotBackend}, ax, d::KW, smooth::Bool)
@@ -272,13 +294,13 @@ handleSmooth(plt::Plot{PyPlotBackend}, ax, d::KW, smooth::Real) = handleSmooth(p
# ---------------------------------------------------------------------------
-makePyPlotCurrent(wrap::PyPlotAxisWrapper) = wrap.ax == nothing ? PyPlot.figure(wrap.fig.o[:number]) : nothing
-makePyPlotCurrent(plt::Plot{PyPlotBackend}) = plt.o == nothing ? nothing : makePyPlotCurrent(plt.o)
-
-
-function _before_add_series(plt::Plot{PyPlotBackend})
- makePyPlotCurrent(plt)
-end
+# makePyPlotCurrent(wrap::PyPlotAxisWrapper) = wrap.ax == nothing ? PyPlot.figure(wrap.fig.o[:number]) : nothing
+# makePyPlotCurrent(plt::Plot{PyPlotBackend}) = plt.o == nothing ? nothing : makePyPlotCurrent(plt.o)
+#
+#
+# function _before_add_series(plt::Plot{PyPlotBackend})
+# makePyPlotCurrent(plt)
+# end
# ------------------------------------------------------------------
@@ -297,7 +319,7 @@ function pyplot_figure(plotargs::KW)
fig[:set_size_inches](w, h, forward = true)
fig[:set_facecolor](getPyPlotColor(plotargs[:background_color_outside]))
fig[:set_dpi](DPI)
- fig[:set_tight_layout](true)
+ # fig[:set_tight_layout](true)
# clear the figure
PyPlot.clf()
@@ -315,21 +337,27 @@ end
# ---------------------------------------------------------------------------
-function _create_backend_figure(plt::Plot)
- if haskey(plt.plotargs, :subplot)
- wrap = nothing
- else
- wrap = PyPlotAxisWrapper(nothing, nothing, pyplot_figure(plt.plotargs), [])
- pyplot_3d_setup!(wrap, plt.plotargs)
- if get(plt.plotargs, :polar, false)
- push!(wrap.kwargs, (:polar, true))
- end
- end
- wrap
- # plt = Plot(wrap, pkg, 0, plt.plotargs, KW[])
- # plt
+function _create_backend_figure(plt::Plot{PyPlotBackend})
+ fig = pyplot_figure(plt.plotargs)
+ # TODO: handle 3d and polar
+ fig
end
+# function _create_backend_figure(plt::Plot)
+# if haskey(plt.plotargs, :subplot)
+# wrap = nothing
+# else
+# wrap = PyPlotAxisWrapper(nothing, nothing, pyplot_figure(plt.plotargs), [])
+# pyplot_3d_setup!(wrap, plt.plotargs)
+# if get(plt.plotargs, :polar, false)
+# push!(wrap.kwargs, (:polar, true))
+# end
+# end
+# wrap
+# # plt = Plot(wrap, pkg, 0, plt.plotargs, KW[])
+# # plt
+# end
+
# ---------------------------------------------------------------------------
function fix_xy_lengths!(plt::Plot{PyPlotBackend}, d::KW)
@@ -368,11 +396,12 @@ pyfillcolormap(d::KW) = getPyPlotColorMap(d[:fillcolor], d[:fillalpha])
function _add_series(plt::Plot{PyPlotBackend}, series::Series)
d = series.d
st = d[:seriestype]
- if !(st in supportedTypes(pkg))
- error("seriestype $(st) is unsupported in PyPlot. Choose from: $(supportedTypes(pkg))")
+ if !(st in supportedTypes(plt.backend))
+ error("seriestype $(st) is unsupported in PyPlot. Choose from: $(supportedTypes(plt.backend))")
end
# 3D plots have a different underlying Axes object in PyPlot
+ # TODO: BUG: this adds to kwargs but never changes anything... source of subplot(wireframe(...)) bug?
if st in _3dTypes && isempty(plt.o.kwargs)
push!(plt.o.kwargs, (:projection, "3d"))
end
@@ -380,7 +409,8 @@ function _add_series(plt::Plot{PyPlotBackend}, series::Series)
# PyPlot doesn't handle mismatched x/y
fix_xy_lengths!(plt, d)
- ax = getAxis(plt, d[:axis])
+ # ax = getAxis(plt, d[:axis])
+ ax = getAxis(plt, get(d, :subplot, plt.subplots[1]))
x, y, z = d[:x], d[:y], d[:z]
@show typeof((x,y,z))
xyargs = (st in _3dTypes ? (x,y,z) : (x,y))
@@ -769,11 +799,11 @@ end
# given a dimension (:x, :y, or :z), loop over the seriesargs KWs to find the min/max of the underlying data
-function minmaxseries(ds, dimension, axis)
+function minmaxseries(series_list, dimension, axis)
lo, hi = Inf, -Inf
- for d in ds
- d[:axis] == axis || continue
- v = d[dimension]
+ for series in series_list
+ series.d[:axis] == axis || continue
+ v = series.d[dimension]
if length(v) > 0
vlo, vhi = extrema(v)
lo = min(lo, vlo)
@@ -795,13 +825,13 @@ function set_lims!(plt::Plot{PyPlotBackend}, axis::Symbol)
ax = getAxis(plt, axis)
pargs = plt.plotargs
if pargs[:xlims] == :auto
- ax[pargs[:polar] ? :set_tlim : :set_xlim](minmaxseries(plt.seriesargs, :x, axis)...)
+ ax[pargs[:polar] ? :set_tlim : :set_xlim](minmaxseries(plt.series_list, :x, axis)...)
end
if pargs[:ylims] == :auto
- ax[pargs[:polar] ? :set_rlim : :set_ylim](minmaxseries(plt.seriesargs, :y, axis)...)
+ ax[pargs[:polar] ? :set_rlim : :set_ylim](minmaxseries(plt.series_list, :y, axis)...)
end
if pargs[:zlims] == :auto && haskey(ax, :set_zlim)
- ax[:set_zlim](minmaxseries(plt.seriesargs, :z, axis)...)
+ ax[:set_zlim](minmaxseries(plt.series_list, :z, axis)...)
end
end
@@ -811,7 +841,7 @@ end
# the x/y data for each handle (for example, plot and scatter)
function setxy!{X,Y}(plt::Plot{PyPlotBackend}, xy::Tuple{X,Y}, i::Integer)
- d = plt.seriesargs[i]
+ d = plt.series_list[i].d
d[:x], d[:y] = xy
for handle in d[:serieshandle]
try
@@ -826,7 +856,7 @@ end
function setxyz!{X,Y,Z}(plt::Plot{PyPlotBackend}, xyz::Tuple{X,Y,Z}, i::Integer)
- d = plt.seriesargs[i]
+ d = plt.series_list[i].d
d[:x], d[:y], d[:z] = xyz
for handle in d[:serieshandle]
handle[:set_data](d[:x], d[:y])
@@ -901,9 +931,9 @@ function updateAxisColors(ax, d::KW)
ax[:title][:set_color](guidecolor)
end
-function usingRightAxis(plt::Plot{PyPlotBackend})
- any(args -> args[:axis] in (:right,:auto), plt.seriesargs)
-end
+# function usingRightAxis(plt::Plot{PyPlotBackend})
+# any(args -> args[:axis] in (:right,:auto), plt.seriesargs)
+# end
# --------------------------------------------------------------------------
@@ -912,7 +942,8 @@ end
function _update_plot(plt::Plot{PyPlotBackend}, d::KW)
# @show d
figorax = plt.o
- ax = getLeftAxis(figorax)
+ # ax = getLeftAxis(figorax)
+ ax = getAxis(plt, plt.subplots[1])
# ticksz = get(d, :tickfont, plt.plotargs[:tickfont]).pointsize
guidesz = get(d, :guidefont, plt.plotargs[:guidefont]).pointsize
@@ -920,15 +951,16 @@ function _update_plot(plt::Plot{PyPlotBackend}, d::KW)
haskey(d, :title) && ax[:set_title](d[:title])
ax[:title][:set_fontsize](guidesz)
- # handle right y axis
- axes = [getLeftAxis(figorax)]
- if usingRightAxis(plt)
- push!(axes, getRightAxis(figorax))
- if get(d, :yrightlabel, "") != ""
- rightax = getRightAxis(figorax)
- rightax[:set_ylabel](d[:yrightlabel])
- end
- end
+ axes = [ax]
+ # # handle right y axis
+ # axes = [getLeftAxis(figorax)]
+ # if usingRightAxis(plt)
+ # push!(axes, getRightAxis(figorax))
+ # if get(d, :yrightlabel, "") != ""
+ # rightax = getRightAxis(figorax)
+ # rightax[:set_ylabel](d[:yrightlabel])
+ # end
+ # end
for letter in ("x", "y", "z")
axissym = symbol(letter*"axis")
@@ -1044,7 +1076,7 @@ end
#
# # this will be called internally, when creating a subplot from existing plots
# # NOTE: if I ever need to "Rebuild a "ubplot from individual Plot's"... this is what I should use!
-# function subplot(plts::AVec{Plot{PyPlotBackend}}, layout::SubplotLayout, d::KW)
+# function subplot(plts::AVec{Plot{PyPlotBackend}}, layout::AbstractLayout, d::KW)
# validateSubplotSupported()
#
# p = length(layout)
@@ -1104,15 +1136,27 @@ function addPyPlotLegend(plt::Plot, ax)
leg = plt.plotargs[:legend]
if leg != :none
# gotta do this to ensure both axes are included
- args = filter(x -> !(x[:seriestype] in (
- :hist,:density,:hexbin,:hist2d,:hline,:vline,
- :contour,:contour3d,:surface,:wireframe,
- :heatmap,:path3d,:scatter3d, :pie, :image
- )), plt.seriesargs)
- args = filter(x -> x[:label] != "", args)
- if length(args) > 0
- leg = ax[:legend]([d[:serieshandle][1] for d in args],
- [d[:label] for d in args],
+ labels = []
+ handles = []
+ for series in plt.series_list
+ if series.d[:label] != "" && !(series.d[:seriestype] in (
+ :hist,:density,:hexbin,:hist2d,:hline,:vline,
+ :contour,:contour3d,:surface,:wireframe,
+ :heatmap,:path3d,:scatter3d, :pie, :image))
+ push!(handles, series.d[:serieshandle][1])
+ push!(labels, series.d[:label])
+ end
+ end
+ # args = filter(x -> !(x.d[:seriestype] in (
+ # :hist,:density,:hexbin,:hist2d,:hline,:vline,
+ # :contour,:contour3d,:surface,:wireframe,
+ # :heatmap,:path3d,:scatter3d, :pie, :image
+ # )), plt.series_list)
+ # args = filter(x -> x[:label] != "", args)
+ # if length(args) > 0
+ if !isempty(handles)
+ leg = ax[:legend](handles, #[d[:serieshandle][1] for d in args],
+ labels, #[d[:label] for d in args],
loc = get(_pyplot_legend_pos, leg, "best"),
scatterpoints = 1,
fontsize = plt.plotargs[:legendfont].pointsize
diff --git a/src/backends/qwt.jl b/src/backends/qwt.jl
index 0e7a1904..87eb6211 100644
--- a/src/backends/qwt.jl
+++ b/src/backends/qwt.jl
@@ -269,28 +269,28 @@ end
# -------------------------------
-# create the underlying object (each backend will do this differently)
-function _create_subplot(subplt::Subplot{QwtBackend}, isbefore::Bool)
- isbefore && return false
- i = 0
- rows = Any[]
- row = Any[]
- for (i,(r,c)) in enumerate(subplt.layout)
- push!(row, subplt.plts[i].o)
- if c == ncols(subplt.layout, r)
- push!(rows, Qwt.hsplitter(row...))
- row = Any[]
- end
- end
- # for rowcnt in subplt.layout.rowcounts
- # push!(rows, Qwt.hsplitter([plt.o for plt in subplt.plts[(1:rowcnt) + i]]...))
- # i += rowcnt
- # end
- subplt.o = Qwt.vsplitter(rows...)
- # Qwt.resizewidget(subplt.o, getplotargs(subplt,1)[:size]...)
- # Qwt.moveToLastScreen(subplt.o) # hack so it goes to my center monitor... sorry
- true
-end
+# # create the underlying object (each backend will do this differently)
+# function _create_subplot(subplt::Subplot{QwtBackend}, isbefore::Bool)
+# isbefore && return false
+# i = 0
+# rows = Any[]
+# row = Any[]
+# for (i,(r,c)) in enumerate(subplt.layout)
+# push!(row, subplt.plts[i].o)
+# if c == ncols(subplt.layout, r)
+# push!(rows, Qwt.hsplitter(row...))
+# row = Any[]
+# end
+# end
+# # for rowcnt in subplt.layout.rowcounts
+# # push!(rows, Qwt.hsplitter([plt.o for plt in subplt.plts[(1:rowcnt) + i]]...))
+# # i += rowcnt
+# # end
+# subplt.o = Qwt.vsplitter(rows...)
+# # Qwt.resizewidget(subplt.o, getplotargs(subplt,1)[:size]...)
+# # Qwt.moveToLastScreen(subplt.o) # hack so it goes to my center monitor... sorry
+# true
+# end
function _expand_limits(lims, plt::Plot{QwtBackend}, isx::Bool)
for series in plt.o.lines
@@ -311,13 +311,13 @@ function Base.writemime(io::IO, ::MIME"image/png", plt::Plot{QwtBackend})
write(io, readall("/tmp/dfskjdhfkh.png"))
end
-function Base.writemime(io::IO, ::MIME"image/png", subplt::Subplot{QwtBackend})
- for plt in subplt.plts
- Qwt.refresh(plt.o)
- end
- Qwt.savepng(subplt.o, "/tmp/dfskjdhfkh.png")
- write(io, readall("/tmp/dfskjdhfkh.png"))
-end
+# function Base.writemime(io::IO, ::MIME"image/png", subplt::Subplot{QwtBackend})
+# for plt in subplt.plts
+# Qwt.refresh(plt.o)
+# end
+# Qwt.savepng(subplt.o, "/tmp/dfskjdhfkh.png")
+# write(io, readall("/tmp/dfskjdhfkh.png"))
+# end
function Base.display(::PlotsDisplay, plt::Plot{QwtBackend})
@@ -325,9 +325,9 @@ function Base.display(::PlotsDisplay, plt::Plot{QwtBackend})
Qwt.showwidget(plt.o)
end
-function Base.display(::PlotsDisplay, subplt::Subplot{QwtBackend})
- for plt in subplt.plts
- Qwt.refresh(plt.o)
- end
- Qwt.showwidget(subplt.o)
-end
+# function Base.display(::PlotsDisplay, subplt::Subplot{QwtBackend})
+# for plt in subplt.plts
+# Qwt.refresh(plt.o)
+# end
+# Qwt.showwidget(subplt.o)
+# end
diff --git a/src/backends/template.jl b/src/backends/template.jl
index 537903e9..db01eb2e 100644
--- a/src/backends/template.jl
+++ b/src/backends/template.jl
@@ -57,9 +57,9 @@ end
# ----------------------------------------------------------------
-function _create_subplot(subplt::Subplot{[PkgName]AbstractBackend}, isbefore::Bool)
- # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
-end
+# function _create_subplot(subplt::Subplot{[PkgName]AbstractBackend}, isbefore::Bool)
+# # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
+# end
function _expand_limits(lims, plt::Plot{[PkgName]AbstractBackend}, isx::Bool)
# TODO: call expand limits for each plot data
@@ -79,6 +79,6 @@ function Base.display(::PlotsDisplay, plt::Plot{[PkgName]AbstractBackend})
# TODO: display/show the plot
end
-function Base.display(::PlotsDisplay, plt::Subplot{[PkgName]AbstractBackend})
- # TODO: display/show the subplot
-end
+# function Base.display(::PlotsDisplay, plt::Subplot{[PkgName]AbstractBackend})
+# # TODO: display/show the subplot
+# end
diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl
index 80e7a8e1..d2bd5f3c 100644
--- a/src/backends/unicodeplots.jl
+++ b/src/backends/unicodeplots.jl
@@ -247,10 +247,10 @@ end
# we don't do very much for subplots... just stack them vertically
-function _create_subplot(subplt::Subplot{UnicodePlotsBackend}, isbefore::Bool)
- isbefore && return false
- true
-end
+# function _create_subplot(subplt::Subplot{UnicodePlotsBackend}, isbefore::Bool)
+# isbefore && return false
+# true
+# end
function Base.display(::PlotsDisplay, plt::Plot{UnicodePlotsBackend})
@@ -260,8 +260,8 @@ end
-function Base.display(::PlotsDisplay, subplt::Subplot{UnicodePlotsBackend})
- for plt in subplt.plts
- gui(plt)
- end
-end
+# function Base.display(::PlotsDisplay, subplt::Subplot{UnicodePlotsBackend})
+# for plt in subplt.plts
+# gui(plt)
+# end
+# end
diff --git a/src/backends/winston.jl b/src/backends/winston.jl
index 4ea2ce54..6b90b457 100644
--- a/src/backends/winston.jl
+++ b/src/backends/winston.jl
@@ -261,9 +261,9 @@ end
# ----------------------------------------------------------------
-function _create_subplot(subplt::Subplot{WinstonBackend}, isbefore::Bool)
- # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
-end
+# function _create_subplot(subplt::Subplot{WinstonBackend}, isbefore::Bool)
+# # TODO: build the underlying Subplot object. this is where you might layout the panes within a GUI window, for example
+# end
# ----------------------------------------------------------------
@@ -302,6 +302,6 @@ function Base.display(::PlotsDisplay, plt::Plot{WinstonBackend})
end
-function Base.display(::PlotsDisplay, subplt::Subplot{WinstonBackend})
- # TODO: display/show the Subplot object
-end
+# function Base.display(::PlotsDisplay, subplt::Subplot{WinstonBackend})
+# # TODO: display/show the Subplot object
+# end
diff --git a/src/components.jl b/src/components.jl
index 84867249..9e073868 100644
--- a/src/components.jl
+++ b/src/components.jl
@@ -257,10 +257,6 @@ function text(str, args...)
end
# -----------------------------------------------------------------------
-# simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place
-type Axis #<: Associative{Symbol,Any}
- d::KW
-end
xaxis(args...) = Axis("x", args...)
yaxis(args...) = Axis("y", args...)
@@ -299,7 +295,7 @@ function Axis(letter::AbstractString, args...; kw...)
end
# update an Axis object with magic args and keywords
-function update!(a::Axis, args..., kw...)
+function update!(a::Axis, args...; kw...)
# first process args
d = a.d
for arg in args
diff --git a/src/old_layouts.jl b/src/old_layouts.jl
index 76f1bde8..8261a4d6 100644
--- a/src/old_layouts.jl
+++ b/src/old_layouts.jl
@@ -4,7 +4,7 @@
# -----------------------------------------------------------
"Simple grid, indices are row-major."
-immutable GridLayout <: SubplotLayout
+immutable GridLayout <: AbstractLayout
nr::Int
nc::Int
end
@@ -30,7 +30,7 @@ Base.getindex(layout::GridLayout, r::Int, c::Int) = (r-1) * layout.nc + c
# -----------------------------------------------------------
"Number of plots per row"
-immutable RowsLayout <: SubplotLayout
+immutable RowsLayout <: AbstractLayout
numplts::Int
rowcounts::AbstractVector{Int}
end
@@ -62,7 +62,7 @@ Base.getindex(layout::RowsLayout, r::Int, c::Int) = sum(layout.rowcounts[1:r-1])
# -----------------------------------------------------------
"Flexible, nested layout with optional size percentages."
-immutable FlexLayout <: SubplotLayout
+immutable FlexLayout <: AbstractLayout
n::Int
grid::Matrix # Nested layouts. Each position
# can be a plot index or another FlexLayout
diff --git a/src/old_subplot.jl b/src/old_subplot.jl
index 67baa993..64846daa 100644
--- a/src/old_subplot.jl
+++ b/src/old_subplot.jl
@@ -100,7 +100,7 @@ function subplot{P,I<:Integer}(pltsPerRow::AVec{I}, plt1::Plot{P}, plts::Plot{P}
end
# this will be called internally
-function subplot{P<:AbstractBackend}(plts::AVec{Plot{P}}, layout::SubplotLayout, d::KW)
+function subplot{P<:AbstractBackend}(plts::AVec{Plot{P}}, layout::AbstractLayout, d::KW)
validateSubplotSupported()
p = length(layout)
n = sum([plt.n for plt in plts])
diff --git a/src/plot.jl b/src/plot.jl
index f4f1f3ef..0a7b8726 100644
--- a/src/plot.jl
+++ b/src/plot.jl
@@ -47,10 +47,15 @@ function plot(args...; kw...)
d = KW(kw)
preprocessArgs!(d)
+ layout = pop!(d, :layout, Subplot())
+ subplots = Subplot[layout] # TODO: build full list
+ smap = SubplotMap(1 => layout) # TODO: actually build a map
+
+ # TODO: this seems wrong... I only call getPlotArgs when creating a new plot??
plotargs = merge(d, getPlotArgs(pkg, d, 1))
# plt = _create_plot(pkg, plotargs) # create a new, blank plot
- plt = Plot(nothing, pkg, 0, plt.plotargs, KW[])
+ plt = Plot(nothing, pkg, 0, plotargs, Series[], subplots, smap, layout)
plt.o = _create_backend_figure(plt)
# now update the plot
diff --git a/src/series_new.jl b/src/series_new.jl
index b5e2a5c5..07752e40 100644
--- a/src/series_new.jl
+++ b/src/series_new.jl
@@ -2,11 +2,7 @@
# we are going to build recipes to do the processing and splitting of the args
-# build the argument dictionary for a series
-# function getSeriesArgs(pkg::AbstractBackend, plotargs::KW, d, commandIndex::Int, plotIndex::Int, globalIndex::Int) # TODO, pass in plotargs, not plt
function _add_defaults!(d::KW, plt::Plot, commandIndex::Int)
- # kwdict = KW(d)
- # d = KW()
pkg = plt.backend
n = plt.n
plotargs = getplotargs(plt, n)
@@ -18,16 +14,10 @@ function _add_defaults!(d::KW, plt::Plot, commandIndex::Int)
setDictValue(d, d, k, commandIndex, _seriesDefaults)
end
- # # groupby args?
- # for k in (:idxfilter, :numUncounted, :dataframe)
- # if haskey(kwdict, k)
- # d[k] = kwdict[k]
- # end
- # end
-
- # if haskey(_typeAliases, d[:seriestype])
- # d[:seriestype] = _typeAliases[d[:seriestype]]
- # end
+ if d[:subplot_index] == :auto
+ # TODO: something useful
+ d[:subplot_index] = 1
+ end
aliasesAndAutopick(d, :axis, _axesAliases, supportedAxes(pkg), plotIndex)
aliasesAndAutopick(d, :linestyle, _styleAliases, supportedStyles(pkg), plotIndex)
@@ -76,9 +66,7 @@ function _add_defaults!(d::KW, plt::Plot, commandIndex::Int)
label = string(label, " (R)")
end
d[:label] = label
-
- # warnOnUnsupported(pkg, d)
-
+
d
end
diff --git a/src/subplots.jl b/src/subplots.jl
index 1e99829f..b024c95e 100644
--- a/src/subplots.jl
+++ b/src/subplots.jl
@@ -1,18 +1,24 @@
-# -----------------------------------------------------------
-# GridLayout
-# -----------------------------------------------------------
+Base.size(layout::EmptyLayout) = (0,0)
+Base.length(layout::EmptyLayout) = 0
+Base.getindex(layout::EmptyLayout, r::Int, c::Int) = nothing
+
+
+Base.size(layout::RootLayout) = (1,1)
+Base.length(layout::RootLayout) = 1
+# Base.getindex(layout::RootLayout, r::Int, c::Int) = layout.child
+
+Base.size(subplot::Subplot) = (1,1)
+Base.length(subplot::Subplot) = 1
+Base.getindex(subplot::Subplot, r::Int, c::Int) = subplot
-"nested, gridded layout with optional size percentages."
-immutable GridLayout <: SubplotLayout
- grid::Matrix # Nested layouts. Each position is an AbstractSubplot or another GridLayout
- widths::Vector{Float64}
- heights::Vector{Float64}
-end
Base.size(layout::GridLayout) = size(layout.grid)
Base.length(layout::GridLayout) = length(layout.grid)
+Base.getindex(layout::GridLayout, r::Int, c::Int) = layout.grid[r,c]
+
+
# Base.start(layout::GridLayout) = 1
# Base.done(layout::GridLayout, state) = state > length(layout)
# function Base.next(layout::GridLayout, state)
@@ -31,11 +37,10 @@ Base.length(layout::GridLayout) = length(layout.grid)
# (r,c), state + 1
# end
-nrows(layout::GridLayout) = size(layout, 1)
-ncols(layout::GridLayout) = size(layout, 2)
+# nrows(layout::GridLayout) = size(layout, 1)
+# ncols(layout::GridLayout) = size(layout, 2)
# get the plot index given row and column
-Base.getindex(layout::GridLayout, r::Int, c::Int) = layout.grid[r,c]
# -----------------------------------------------------------
diff --git a/src/types.jl b/src/types.jl
index 0f581d79..aa7c5ba5 100644
--- a/src/types.jl
+++ b/src/types.jl
@@ -16,39 +16,74 @@ end
wrap{T}(obj::T) = InputWrapper{T}(obj)
Base.isempty(wrapper::InputWrapper) = false
+# -----------------------------------------------------------
+# Axes
+# -----------------------------------------------------------
+
+# simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place
+type Axis #<: Associative{Symbol,Any}
+ d::KW
+end
+
type AxisView
label::UTF8String
axis::Axis
end
-abstract AbstractSubplot
-immutable EmptySubplot <: AbstractSubplot end
-type Subplot <: AbstractSubplot
- axisviews::Vector{AxisView}
- subplotargs::KW # args specific to this subplot
- obj # can store backend-specific data... like a pyplot ax
+# -----------------------------------------------------------
+# Layouts
+# -----------------------------------------------------------
+
+abstract AbstractLayout
+
+# -----------------------------------------------------------
+
+# contains blank space
+immutable EmptyLayout <: AbstractLayout end
+
+# this is the parent of the top-level layout
+immutable RootLayout <: AbstractLayout
+ # child::AbstractLayout
end
-type Series
- d::KW
- # x
- # y
- # z
- # subplots::Vector{Subplot}
+# -----------------------------------------------------------
+
+# a single subplot
+type Subplot <: AbstractLayout
+ parent::AbstractLayout
+ attr::KW # args specific to this subplot
+ # axisviews::Vector{AxisView}
+ o # can store backend-specific data... like a pyplot ax
+
+ # Subplot(parent = RootLayout(); attr = KW())
end
-# function Series(d::KW)
-# x = pop!(d, :x)
-# y = pop!(d, :y)
-# z = pop!(d, :z)
-# Series(d, x, y, z)
-# end
+Subplot() = Subplot(RootLayout(), KW(), nothing)
+
+# -----------------------------------------------------------
+
+# nested, gridded layout with optional size percentages
+immutable GridLayout <: AbstractLayout
+ parent::AbstractLayout
+ grid::Matrix{AbstractLayout} # Nested layouts. Each position is a AbstractLayout, which allows for arbitrary recursion
+ # widths::Vector{Float64}
+ # heights::Vector{Float64}
+ attr::KW
+end
+
+# -----------------------------------------------------------
+
+typealias SubplotMap Dict{Any, Subplot}
# -----------------------------------------------------------
# Plot
# -----------------------------------------------------------
+type Series
+ d::KW
+end
+
type Plot{T<:AbstractBackend} <: AbstractPlot{T}
o # the backend's plot object
backend::T # the backend type
@@ -57,19 +92,15 @@ type Plot{T<:AbstractBackend} <: AbstractPlot{T}
# seriesargs::Vector{KW} # arguments for each series
series_list::Vector{Series} # arguments for each series
subplots::Vector{Subplot}
+ subplot_map::SubplotMap # provide any label as a map to a subplot
+ layout::AbstractLayout
end
-# -----------------------------------------------------------
-# Layout
-# -----------------------------------------------------------
-
-abstract SubplotLayout
-
# -----------------------------------------------------------
# Subplot
# -----------------------------------------------------------
-# type Subplot{T<:AbstractBackend, L<:SubplotLayout} <: AbstractPlot{T}
+# type Subplot{T<:AbstractBackend, L<:AbstractLayout} <: AbstractPlot{T}
# o # the underlying object
# plts::Vector{Plot{T}} # the individual plots
# backend::T