backend template renaming/reorg/cleanup, pyplot fixes
This commit is contained in:
parent
d4d388a94b
commit
ef0d99340a
@ -51,6 +51,7 @@ like_line(seriestype::Symbol) = seriestype in (:line, :path, :steppre, :ste
|
|||||||
like_surface(seriestype::Symbol) = seriestype in (:contour, :contour3d, :heatmap, :surface, :wireframe, :image)
|
like_surface(seriestype::Symbol) = seriestype in (:contour, :contour3d, :heatmap, :surface, :wireframe, :image)
|
||||||
|
|
||||||
is3d(seriestype::Symbol) = seriestype in _3dTypes
|
is3d(seriestype::Symbol) = seriestype in _3dTypes
|
||||||
|
is3d(series::Series) = is3d(series.d)
|
||||||
is3d(d::KW) = trueOrAllTrue(is3d, d[:seriestype])
|
is3d(d::KW) = trueOrAllTrue(is3d, d[:seriestype])
|
||||||
|
|
||||||
const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
const _allStyles = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
|
||||||
|
|||||||
@ -53,10 +53,10 @@ _update_plot(pkg::AbstractBackend, plt::Plot, d::KW) = error("_update_plot($pkg
|
|||||||
|
|
||||||
# don't do anything as a default
|
# don't do anything as a default
|
||||||
_create_backend_figure(plt::Plot) = nothing
|
_create_backend_figure(plt::Plot) = nothing
|
||||||
_before_add_series(plt::Plot) = nothing
|
_before_update(plt::Plot) = nothing
|
||||||
_add_series(plt::Plot) = nothing
|
_series_added(plt::Plot) = nothing
|
||||||
_add_annotations{X,Y,V}(plt::Plot, anns::AVec{Tuple{X,Y,V}}) = nothing
|
# _add_annotations{X,Y,V}(plt::Plot, anns::AVec{Tuple{X,Y,V}}) = nothing
|
||||||
_update_plot_pos_size(plt::AbstractPlot, d::KW) = nothing
|
# _update_plot_pos_size(plt::AbstractPlot, d::KW) = nothing
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -79,13 +79,6 @@ function _initialize_backend(::BokehBackend; kw...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# make255(x) = round(Int, 255 * x)
|
|
||||||
|
|
||||||
# function bokehcolor(c::Colorant)
|
|
||||||
# @sprintf("rgba(%d, %d, %d, %1.3f)", [make255(f(c)) for f in [red,green,blue]]..., alpha(c))
|
|
||||||
# end
|
|
||||||
# bokehcolor(cs::ColorScheme) = bokehcolor(getColor(cs))
|
|
||||||
|
|
||||||
|
|
||||||
const _glyphtypes = KW(
|
const _glyphtypes = KW(
|
||||||
:ellipse => :Circle,
|
:ellipse => :Circle,
|
||||||
@ -154,8 +147,8 @@ function _create_backend_figure(plt::Plot{BokehBackend})
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# function _add_series(::BokehBackend, plt::Plot, d::KW)
|
# function _series_added(::BokehBackend, plt::Plot, d::KW)
|
||||||
function _add_series(plt::Plot{BokehBackend}, series::Series)
|
function _series_added(plt::Plot{BokehBackend}, series::Series)
|
||||||
bdata = Dict{Symbol, Vector}(:x => collect(series.d[:x]), :y => collect(series.d[:y]))
|
bdata = Dict{Symbol, Vector}(:x => collect(series.d[:x]), :y => collect(series.d[:y]))
|
||||||
|
|
||||||
glyph = Bokeh.Bokehjs.Glyph(
|
glyph = Bokeh.Bokehjs.Glyph(
|
||||||
@ -180,9 +173,6 @@ end
|
|||||||
function _update_plot(plt::Plot{BokehBackend}, d::KW)
|
function _update_plot(plt::Plot{BokehBackend}, d::KW)
|
||||||
end
|
end
|
||||||
|
|
||||||
function _update_plot_pos_size(plt::AbstractPlot{BokehBackend}, d::KW)
|
|
||||||
end
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
# accessors for x/y data
|
# accessors for x/y data
|
||||||
@ -199,29 +189,9 @@ end
|
|||||||
# end
|
# end
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
|
||||||
|
|
||||||
function _add_annotations{X,Y,V}(plt::Plot{BokehBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
|
||||||
for ann in anns
|
|
||||||
# TODO: add the annotation to the plot
|
|
||||||
end
|
|
||||||
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)
|
|
||||||
# TODO: call expand limits for each plot data
|
|
||||||
end
|
|
||||||
|
|
||||||
function _remove_axis(plt::Plot{BokehBackend}, isx::Bool)
|
|
||||||
# TODO: if plot is inner subplot, might need to remove ticks or axis labels
|
|
||||||
end
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@ -580,8 +580,8 @@ end
|
|||||||
|
|
||||||
|
|
||||||
# plot one data series
|
# plot one data series
|
||||||
# function _add_series(::GadflyBackend, plt::Plot, d::KW)
|
# function _series_added(::GadflyBackend, plt::Plot, d::KW)
|
||||||
function _add_series(plt::Plot{GadflyBackend}, series::Series)
|
function _series_added(plt::Plot{GadflyBackend}, series::Series)
|
||||||
# first clear out the temporary layer
|
# first clear out the temporary layer
|
||||||
gplt = getGadflyContext(plt)
|
gplt = getGadflyContext(plt)
|
||||||
if gplt.layers[1].geom.tag == :remove
|
if gplt.layers[1].geom.tag == :remove
|
||||||
|
|||||||
@ -95,8 +95,8 @@ function _create_backend_figure(plt::Plot{GLVisualizeBackend})
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# function _add_series(::GLVisualizeBackend, plt::Plot, d::KW)
|
# function _series_added(::GLVisualizeBackend, plt::Plot, d::KW)
|
||||||
function _add_series(plt::Plot{GLVisualizeBackend}, series::Series)
|
function _series_added(plt::Plot{GLVisualizeBackend}, series::Series)
|
||||||
# TODO: add one series to the underlying package
|
# TODO: add one series to the underlying package
|
||||||
# push!(plt.seriesargs, d)
|
# push!(plt.seriesargs, d)
|
||||||
# TODO: this should be moved to the display method?
|
# TODO: this should be moved to the display method?
|
||||||
|
|||||||
@ -873,7 +873,7 @@ end
|
|||||||
# Plot(nothing, pkg, 0, d, KW[])
|
# Plot(nothing, pkg, 0, d, KW[])
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# function _add_series(::GRBackend, plt::Plot, d::KW)
|
# function _series_added(::GRBackend, plt::Plot, d::KW)
|
||||||
# push!(plt.seriesargs, d)
|
# push!(plt.seriesargs, d)
|
||||||
# plt
|
# plt
|
||||||
# end
|
# end
|
||||||
|
|||||||
@ -42,13 +42,13 @@ end
|
|||||||
|
|
||||||
|
|
||||||
# # plot one data series
|
# # plot one data series
|
||||||
# function _add_series(::ImmerseBackend, plt::Plot, d::KW)
|
# function _series_added(::ImmerseBackend, plt::Plot, d::KW)
|
||||||
# addGadflySeries!(plt, d)
|
# addGadflySeries!(plt, d)
|
||||||
# push!(plt.seriesargs, d)
|
# push!(plt.seriesargs, d)
|
||||||
# plt
|
# plt
|
||||||
# end
|
# end
|
||||||
|
|
||||||
function _add_series(plt::Plot{ImmerseBackend}, series::Series)
|
function _series_added(plt::Plot{ImmerseBackend}, series::Series)
|
||||||
addGadflySeries!(plt, series.d)
|
addGadflySeries!(plt, series.d)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -238,7 +238,7 @@ end
|
|||||||
# end
|
# end
|
||||||
|
|
||||||
|
|
||||||
# function _add_series(::PGFPlotsBackend, plt::Plot, d::KW)
|
# function _series_added(::PGFPlotsBackend, plt::Plot, d::KW)
|
||||||
# # TODO: add one series to the underlying package
|
# # TODO: add one series to the underlying package
|
||||||
# push!(plt.seriesargs, d)
|
# push!(plt.seriesargs, d)
|
||||||
# plt
|
# plt
|
||||||
|
|||||||
@ -91,7 +91,7 @@ end
|
|||||||
# end
|
# end
|
||||||
|
|
||||||
|
|
||||||
# function _add_series(::PlotlyBackend, plt::Plot, d::KW)
|
# function _series_added(::PlotlyBackend, plt::Plot, d::KW)
|
||||||
# # TODO: add one series to the underlying package
|
# # TODO: add one series to the underlying package
|
||||||
# push!(plt.seriesargs, d)
|
# push!(plt.seriesargs, d)
|
||||||
# plt
|
# plt
|
||||||
|
|||||||
@ -113,7 +113,7 @@ function _create_backend_figure(plt::Plot{PlotlyJSBackend})
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function _add_series(plt::Plot{PlotlyJSBackend}, series::Series)
|
function _series_added(plt::Plot{PlotlyJSBackend}, series::Series)
|
||||||
d = series.d
|
d = series.d
|
||||||
syncplot = plt.o
|
syncplot = plt.o
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -137,8 +137,8 @@ function _create_backend_figure(plt::Plot{QwtBackend})
|
|||||||
# plt
|
# plt
|
||||||
end
|
end
|
||||||
|
|
||||||
# function _add_series(::QwtBackend, plt::Plot, d::KW)
|
# function _series_added(::QwtBackend, plt::Plot, d::KW)
|
||||||
function _add_series(plt::Plot{QwtBackend}, series::Series)
|
function _series_added(plt::Plot{QwtBackend}, series::Series)
|
||||||
d = adjustQwtKeywords(plt, false; series.d...)
|
d = adjustQwtKeywords(plt, false; series.d...)
|
||||||
fixcolors(d)
|
fixcolors(d)
|
||||||
dumpdict(d,"\n\n!!! plot!")
|
dumpdict(d,"\n\n!!! plot!")
|
||||||
|
|||||||
@ -1,84 +1,74 @@
|
|||||||
|
|
||||||
# TODO: find/replace all [PkgName] with CamelCase, all [pkgname] with lowercase
|
# TODO: find/replace all [PkgName] with CamelCase
|
||||||
|
|
||||||
# [WEBSITE]
|
# [ADD BACKEND WEBSITE]
|
||||||
|
|
||||||
function _initialize_backend(::[PkgName]AbstractBackend; kw...)
|
function _initialize_backend(::[PkgName]AbstractBackend; kw...)
|
||||||
@eval begin
|
@eval begin
|
||||||
import [PkgName]
|
import [PkgName]
|
||||||
export [PkgName]
|
export [PkgName]
|
||||||
# TODO: other initialization that needs to be eval-ed
|
# todo: other initialization that needs to be eval-ed
|
||||||
end
|
end
|
||||||
# TODO: other initialization
|
# todo: other initialization
|
||||||
end
|
end
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Create the window/figure for this backend.
|
||||||
function _create_backend_figure(plt::Plot{[PkgName]Backend})
|
function _create_backend_figure(plt::Plot{[PkgName]Backend})
|
||||||
# TODO: create the window/figure for this backend
|
|
||||||
nothing
|
nothing
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Set up the subplot within the backend object.
|
||||||
function _add_series(plt::Plot{[PkgName]Backend}, series::Series)
|
function _initialize_subplot(plt::Plot{PyPlotBackend}, sp::Subplot{PyPlotBackend})
|
||||||
# TODO: add one series to the underlying package
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# function _add_annotations{X,Y,V}(plt::Plot{[PkgName]AbstractBackend}, anns::AVec{@compat(Tuple{X,Y,V})})
|
# Set the (left, top, right, bottom) minimum padding around the plot area
|
||||||
# for ann in anns
|
# to fit ticks, tick labels, guides, colorbars, etc.
|
||||||
# # TODO: add the annotation to the plot
|
function _update_min_padding!(sp::Subplot{[PkgName]Backend})
|
||||||
# end
|
sp.minpad = (20mm, 5mm, 2mm, 10mm)
|
||||||
# end
|
end
|
||||||
|
|
||||||
|
# Use the bounding boxes (and methods left/top/right/bottom/width/height) `sp.bbox` and `sp.plotarea` to
|
||||||
|
# position the subplot in the backend.
|
||||||
|
function _update_position!(sp::Subplot{[PkgName]Backend})
|
||||||
|
end
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
function _before_update_plot(plt::Plot{[PkgName]AbstractBackend})
|
# This is called before series processing... use it if you need to make the backend object current or something.
|
||||||
|
function _before_update(plt::Plot{[PkgName]AbstractBackend})
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO: override this to update plot items (title, xlabel, etc) after creation
|
|
||||||
|
# Add one series to the underlying backend object.
|
||||||
|
function _series_added(plt::Plot{[PkgName]Backend}, series::Series)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Override this to update plot items (title, xlabel, etc), and add annotations (d[:annotations])
|
||||||
function _update_plot(plt::Plot{[PkgName]AbstractBackend}, d::KW)
|
function _update_plot(plt::Plot{[PkgName]AbstractBackend}, d::KW)
|
||||||
end
|
end
|
||||||
|
|
||||||
function _update_plot_pos_size(plt::AbstractPlot{[PkgName]AbstractBackend}, d::KW)
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
# When series data is added/changed, this callback can do dynamic updates to the backend object.
|
||||||
|
# note: if the backend rebuilds the plot from scratch on display, then you might not do anything here.
|
||||||
|
function _series_updated(plt::Plot{[PkgName]AbstractBackend}, series::Series)
|
||||||
end
|
end
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
# accessors for x/y data
|
# Write a png to io. You could define methods for:
|
||||||
|
# "application/eps" => "eps",
|
||||||
# function getxy(plt::Plot{[PkgName]AbstractBackend}, i::Int)
|
# "image/eps" => "eps",
|
||||||
# # TODO: return a tuple of (x, y) vectors
|
# "application/pdf" => "pdf",
|
||||||
# end
|
# "image/png" => "png",
|
||||||
#
|
# "application/postscript" => "ps",
|
||||||
# function setxy!{X,Y}(plt::Plot{[PkgName]AbstractBackend}, xy::Tuple{X,Y}, i::Integer)
|
# "image/svg+xml" => "svg"
|
||||||
# # TODO: set the plot data from the (x,y) tuple
|
|
||||||
# plt
|
|
||||||
# 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
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# function _remove_axis(plt::Plot{[PkgName]AbstractBackend}, isx::Bool)
|
|
||||||
# # TODO: if plot is inner subplot, might need to remove ticks or axis labels
|
|
||||||
# end
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
|
||||||
|
|
||||||
function Base.writemime(io::IO, ::MIME"image/png", plt::AbstractPlot{[PkgName]AbstractBackend})
|
function Base.writemime(io::IO, ::MIME"image/png", plt::AbstractPlot{[PkgName]AbstractBackend})
|
||||||
# TODO: write a png to io
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Display/show the plot (open a GUI window, or browser page, for example).
|
||||||
function Base.display(::PlotsDisplay, plt::Plot{[PkgName]AbstractBackend})
|
function Base.display(::PlotsDisplay, plt::Plot{[PkgName]AbstractBackend})
|
||||||
# TODO: display/show the plot
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# function Base.display(::PlotsDisplay, plt::Subplot{[PkgName]AbstractBackend})
|
|
||||||
# # TODO: display/show the subplot
|
|
||||||
# end
|
|
||||||
|
|||||||
@ -195,7 +195,7 @@ function _create_backend_figure(plt::Plot{UnicodePlotsBackend})
|
|||||||
# plt
|
# plt
|
||||||
end
|
end
|
||||||
|
|
||||||
function _add_series(plt::Plot{UnicodePlotsBackend}, series::Series)
|
function _series_added(plt::Plot{UnicodePlotsBackend}, series::Series)
|
||||||
d = series.d
|
d = series.d
|
||||||
# TODO don't need these once the "bar" series recipe is done
|
# TODO don't need these once the "bar" series recipe is done
|
||||||
if d[:seriestype] in (:sticks, :bar)
|
if d[:seriestype] in (:sticks, :bar)
|
||||||
|
|||||||
@ -96,7 +96,7 @@ end
|
|||||||
:star5 => "asterisk"
|
:star5 => "asterisk"
|
||||||
)
|
)
|
||||||
|
|
||||||
function _before_add_series(plt::Plot{WinstonBackend})
|
function _before_update(plt::Plot{WinstonBackend})
|
||||||
Winston.ghf(plt.o)
|
Winston.ghf(plt.o)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ function getWinstonItems(plt::Plot)
|
|||||||
window, canvas, wplt
|
window, canvas, wplt
|
||||||
end
|
end
|
||||||
|
|
||||||
function _add_series(plt::Plot{WinstonBackend}, series::Series)
|
function _series_added(plt::Plot{WinstonBackend}, series::Series)
|
||||||
d = series.d
|
d = series.d
|
||||||
window, canvas, wplt = getWinstonItems(plt)
|
window, canvas, wplt = getWinstonItems(plt)
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,8 @@
|
|||||||
const px = AbsoluteLength(0.254)
|
const px = AbsoluteLength(0.254)
|
||||||
const pct = Length{:pct, Float64}(1.0)
|
const pct = Length{:pct, Float64}(1.0)
|
||||||
|
|
||||||
|
const _cbar_width = 5mm
|
||||||
|
|
||||||
Base.(:.*)(m::Measure, n::Number) = m * n
|
Base.(:.*)(m::Measure, n::Number) = m * n
|
||||||
Base.(:.*)(n::Number, m::Measure) = m * n
|
Base.(:.*)(n::Number, m::Measure) = m * n
|
||||||
Base.(:-)(m::Measure, a::AbstractArray) = map(ai -> m - ai, a)
|
Base.(:-)(m::Measure, a::AbstractArray) = map(ai -> m - ai, a)
|
||||||
@ -65,6 +67,15 @@ function crop(parent::BoundingBox, child::BoundingBox)
|
|||||||
BoundingBox(l, t, w, h)
|
BoundingBox(l, t, w, h)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# convert a bounding box from absolute coords to percentages... returns an array of percentages of figure size: [left, bottom, width, height]
|
||||||
|
function bbox_to_pcts(bb::BoundingBox, figw, figh, flipy = true)
|
||||||
|
mms = Float64[f(bb).value for f in (left,bottom,width,height)]
|
||||||
|
if flipy
|
||||||
|
mms[2] = figh.value - mms[2] # flip y when origin in bottom-left
|
||||||
|
end
|
||||||
|
mms ./ Float64[figw.value, figh.value, figw.value, figh.value]
|
||||||
|
end
|
||||||
|
|
||||||
function Base.show(io::IO, bbox::BoundingBox)
|
function Base.show(io::IO, bbox::BoundingBox)
|
||||||
print(io, "BBox{l,t,r,b,w,h = $(left(bbox)),$(top(bbox)), $(right(bbox)),$(bottom(bbox)), $(width(bbox)),$(height(bbox))}")
|
print(io, "BBox{l,t,r,b,w,h = $(left(bbox)),$(top(bbox)), $(right(bbox)),$(bottom(bbox)), $(width(bbox)),$(height(bbox))}")
|
||||||
end
|
end
|
||||||
@ -93,7 +104,7 @@ padding_w(layout::AbstractLayout) = left_padding(layout) + right_padding(layout)
|
|||||||
padding_h(layout::AbstractLayout) = bottom_padding(layout) + top_padding(layout)
|
padding_h(layout::AbstractLayout) = bottom_padding(layout) + top_padding(layout)
|
||||||
padding(layout::AbstractLayout) = (padding_w(layout), padding_h(layout))
|
padding(layout::AbstractLayout) = (padding_w(layout), padding_h(layout))
|
||||||
|
|
||||||
update_position!(layout::AbstractLayout) = nothing
|
_update_position!(layout::AbstractLayout) = nothing
|
||||||
update_child_bboxes!(layout::AbstractLayout) = nothing
|
update_child_bboxes!(layout::AbstractLayout) = nothing
|
||||||
|
|
||||||
width(layout::AbstractLayout) = width(layout.bbox)
|
width(layout::AbstractLayout) = width(layout.bbox)
|
||||||
@ -105,6 +116,11 @@ attr(layout::AbstractLayout, k::Symbol, v) = get(layout.attr, k, v)
|
|||||||
attr!(layout::AbstractLayout, v, k::Symbol) = (layout.attr[k] = v)
|
attr!(layout::AbstractLayout, v, k::Symbol) = (layout.attr[k] = v)
|
||||||
hasattr(layout::AbstractLayout, k::Symbol) = haskey(layout.attr, k)
|
hasattr(layout::AbstractLayout, k::Symbol) = haskey(layout.attr, k)
|
||||||
|
|
||||||
|
leftpad(layout::AbstractLayout) = 0mm
|
||||||
|
toppad(layout::AbstractLayout) = 0mm
|
||||||
|
rightpad(layout::AbstractLayout) = 0mm
|
||||||
|
bottompad(layout::AbstractLayout) = 0mm
|
||||||
|
|
||||||
# -----------------------------------------------------------
|
# -----------------------------------------------------------
|
||||||
# RootLayout
|
# RootLayout
|
||||||
|
|
||||||
@ -138,6 +154,7 @@ Base.getindex(layout::EmptyLayout, r::Int, c::Int) = nothing
|
|||||||
# nested, gridded layout with optional size percentages
|
# nested, gridded layout with optional size percentages
|
||||||
type GridLayout <: AbstractLayout
|
type GridLayout <: AbstractLayout
|
||||||
parent::AbstractLayout
|
parent::AbstractLayout
|
||||||
|
minpad::Tuple # leftpad, toppad, rightpad, bottompad
|
||||||
bbox::BoundingBox
|
bbox::BoundingBox
|
||||||
grid::Matrix{AbstractLayout} # Nested layouts. Each position is a AbstractLayout, which allows for arbitrary recursion
|
grid::Matrix{AbstractLayout} # Nested layouts. Each position is a AbstractLayout, which allows for arbitrary recursion
|
||||||
widths::Vector{Measure}
|
widths::Vector{Measure}
|
||||||
@ -155,6 +172,7 @@ function GridLayout(dims...;
|
|||||||
grid = Matrix{AbstractLayout}(dims...)
|
grid = Matrix{AbstractLayout}(dims...)
|
||||||
layout = GridLayout(
|
layout = GridLayout(
|
||||||
parent,
|
parent,
|
||||||
|
(20mm, 5mm, 2mm, 10mm),
|
||||||
defaultbox,
|
defaultbox,
|
||||||
grid,
|
grid,
|
||||||
Measure[w*pct for w in widths],
|
Measure[w*pct for w in widths],
|
||||||
@ -173,13 +191,39 @@ function Base.setindex!(layout::GridLayout, v, r::Int, c::Int)
|
|||||||
layout.grid[r,c] = v
|
layout.grid[r,c] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
min_padding_left(layout::GridLayout) = maximum(map(min_padding_left, layout.grid[:,1]))
|
leftpad(layout::GridLayout) = layout.minpad[1]
|
||||||
min_padding_top(layout::GridLayout) = maximum(map(min_padding_top, layout.grid[1,:]))
|
toppad(layout::GridLayout) = layout.minpad[2]
|
||||||
min_padding_right(layout::GridLayout) = maximum(map(min_padding_right, layout.grid[:,end]))
|
rightpad(layout::GridLayout) = layout.minpad[3]
|
||||||
min_padding_bottom(layout::GridLayout) = maximum(map(min_padding_bottom, layout.grid[end,:]))
|
bottompad(layout::GridLayout) = layout.minpad[4]
|
||||||
|
|
||||||
|
# min_padding_left(layout::GridLayout) = maximum(map(min_padding_left, layout.grid[:,1]))
|
||||||
|
# min_padding_top(layout::GridLayout) = maximum(map(min_padding_top, layout.grid[1,:]))
|
||||||
|
# min_padding_right(layout::GridLayout) = maximum(map(min_padding_right, layout.grid[:,end]))
|
||||||
|
# min_padding_bottom(layout::GridLayout) = maximum(map(min_padding_bottom, layout.grid[end,:]))
|
||||||
|
|
||||||
|
|
||||||
update_position!(layout::GridLayout) = map(update_position!, layout.grid)
|
# leftpad, toppad, rightpad, bottompad
|
||||||
|
function _update_min_padding!(layout::GridLayout)
|
||||||
|
# minpad_matrix = map(_update_min_padding!, layout.grid)
|
||||||
|
# nr,nc = size(layout)
|
||||||
|
# leftpad = maximum([minpad_matrix[r,1][1] for r=1:nr])
|
||||||
|
# toppad = maximum([minpad_matrix[1,c][2] for c=1:nc])
|
||||||
|
# rightpad = maximum([minpad_matrix[r,end][3] for r=1:nr])
|
||||||
|
# bottompad = maximum([minpad_matrix[end,c][4] for c=1:nc])
|
||||||
|
map(_update_min_padding!, layout.grid)
|
||||||
|
layout.minpad = (
|
||||||
|
maximum(map(leftpad, layout.grid[:,1])),
|
||||||
|
maximum(map(toppad, layout.grid[1,:])),
|
||||||
|
maximum(map(rightpad, layout.grid[:,end])),
|
||||||
|
maximum(map(bottompad, layout.grid[end,:]))
|
||||||
|
)
|
||||||
|
# layout.minpad = (leftpad, toppad, rightpad, bottompad)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function _update_position!(layout::GridLayout)
|
||||||
|
map(_update_position!, layout.grid)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# recursively compute the bounding boxes for the layout and plotarea (relative to canvas!)
|
# recursively compute the bounding boxes for the layout and plotarea (relative to canvas!)
|
||||||
@ -187,10 +231,16 @@ function update_child_bboxes!(layout::GridLayout)
|
|||||||
nr, nc = size(layout)
|
nr, nc = size(layout)
|
||||||
|
|
||||||
# create a matrix for each minimum padding direction
|
# create a matrix for each minimum padding direction
|
||||||
minpad_left = map(min_padding_left, layout.grid)
|
_update_min_padding!(layout)
|
||||||
minpad_top = map(min_padding_top, layout.grid)
|
# minpad_left = map(l -> l.minpad[1], layout.grid)
|
||||||
minpad_right = map(min_padding_right, layout.grid)
|
# minpad_left = map(min_padding_left, layout.grid)
|
||||||
minpad_bottom = map(min_padding_bottom, layout.grid)
|
# minpad_top = map(min_padding_top, layout.grid)
|
||||||
|
# minpad_right = map(min_padding_right, layout.grid)
|
||||||
|
# minpad_bottom = map(min_padding_bottom, layout.grid)
|
||||||
|
minpad_left = map(leftpad, layout.grid)
|
||||||
|
minpad_top = map(toppad, layout.grid)
|
||||||
|
minpad_right = map(rightpad, layout.grid)
|
||||||
|
minpad_bottom = map(bottompad, layout.grid)
|
||||||
# @show minpad_left minpad_top minpad_right minpad_bottom
|
# @show minpad_left minpad_top minpad_right minpad_bottom
|
||||||
|
|
||||||
# get the max horizontal (left and right) padding over columns,
|
# get the max horizontal (left and right) padding over columns,
|
||||||
|
|||||||
168
src/plot.jl
168
src/plot.jl
@ -94,9 +94,7 @@ end
|
|||||||
# natively by the backend
|
# natively by the backend
|
||||||
function _apply_series_recipe(plt::Plot, d::KW)
|
function _apply_series_recipe(plt::Plot, d::KW)
|
||||||
st = d[:seriestype]
|
st = d[:seriestype]
|
||||||
# dumpdict(d, "apply_series_recipe", true)
|
|
||||||
if st in supportedTypes()
|
if st in supportedTypes()
|
||||||
# println("adding series!!")
|
|
||||||
|
|
||||||
# getting ready to add the series... last update to subplot from anything
|
# getting ready to add the series... last update to subplot from anything
|
||||||
# that might have been added during series recipes
|
# that might have been added during series recipes
|
||||||
@ -134,7 +132,7 @@ function _apply_series_recipe(plt::Plot, d::KW)
|
|||||||
warnOnUnsupported(plt.backend, d)
|
warnOnUnsupported(plt.backend, d)
|
||||||
series = Series(d)
|
series = Series(d)
|
||||||
push!(plt.series_list, series)
|
push!(plt.series_list, series)
|
||||||
_add_series(plt, series)
|
_series_added(plt, series)
|
||||||
|
|
||||||
else
|
else
|
||||||
# get a sub list of series for this seriestype
|
# get a sub list of series for this seriestype
|
||||||
@ -158,7 +156,7 @@ end
|
|||||||
# note: at entry, we only have those preprocessed args which were passed in... no default values yet
|
# note: at entry, we only have those preprocessed args which were passed in... no default values yet
|
||||||
function _plot!(plt::Plot, d::KW, args...)
|
function _plot!(plt::Plot, d::KW, args...)
|
||||||
# just in case the backend needs to set up the plot (make it current or something)
|
# just in case the backend needs to set up the plot (make it current or something)
|
||||||
_before_add_series(plt)
|
_before_update(plt)
|
||||||
|
|
||||||
# first apply any args for the subplots
|
# first apply any args for the subplots
|
||||||
for (idx,sp) in enumerate(plt.subplots)
|
for (idx,sp) in enumerate(plt.subplots)
|
||||||
@ -172,15 +170,6 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
args = tuple(extractGroupArgs(d[:group], args...), args...)
|
args = tuple(extractGroupArgs(d[:group], args...), args...)
|
||||||
end
|
end
|
||||||
|
|
||||||
# # initialize the annotations list with what was passed in
|
|
||||||
# # TODO: there must be cleaner way to handle this!
|
|
||||||
# anns = annotations(get(d, :annotation, NTuple{3}[]))
|
|
||||||
# if typeof(anns) <: AVec{PlotText}
|
|
||||||
# anns = NTuple{3}[]
|
|
||||||
# else
|
|
||||||
# delete!(d, :annotation)
|
|
||||||
# end
|
|
||||||
|
|
||||||
|
|
||||||
# for plotting recipes, swap out the args and update the parameter dictionary
|
# for plotting recipes, swap out the args and update the parameter dictionary
|
||||||
# we are keeping a queue of series that still need to be processed.
|
# we are keeping a queue of series that still need to be processed.
|
||||||
@ -212,7 +201,6 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
|
|
||||||
# if there was a grouping, filter the data here
|
# if there was a grouping, filter the data here
|
||||||
_filter_input_data!(kw)
|
_filter_input_data!(kw)
|
||||||
# @show typeof((kw[:x], kw[:y], kw[:z]))
|
|
||||||
|
|
||||||
# map marker_z if it's a Function
|
# map marker_z if it's a Function
|
||||||
if isa(get(kw, :marker_z, nothing), Function)
|
if isa(get(kw, :marker_z, nothing), Function)
|
||||||
@ -250,38 +238,9 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
|
|
||||||
# !!! note: at this point, kw_list is fully decomposed into individual series... one KW per series !!!
|
# !!! note: at this point, kw_list is fully decomposed into individual series... one KW per series !!!
|
||||||
|
|
||||||
# # TODO: move annotations into subplot update
|
|
||||||
# # now include any annotations which were added during recipes
|
|
||||||
# for kw in kw_list
|
|
||||||
# append!(anns, annotations(pop!(kw, :annotation, [])))
|
|
||||||
# end
|
|
||||||
# # @show anns
|
|
||||||
|
|
||||||
|
|
||||||
# for kw in kw_list
|
|
||||||
# @show typeof((kw[:x], kw[:y], kw[:z]))
|
|
||||||
# end
|
|
||||||
|
|
||||||
# # merge plot args... this is where we combine all the plot args from the user and
|
|
||||||
# # from the recipes... axis info, colors, etc
|
|
||||||
# # TODO: why do i need to check for the subplot key?
|
|
||||||
# # if !haskey(d, :subplot)
|
|
||||||
# # for kw in vcat(kw_list, d)
|
|
||||||
# for kw in kw_list
|
|
||||||
# _update_subplot_args(plt, kw[:subplot], kw)
|
|
||||||
# # _add_plotargs!(plt, kw)
|
|
||||||
# end
|
|
||||||
# # handlePlotColors(plt.backend, plt.plotargs)
|
|
||||||
# # end
|
|
||||||
|
|
||||||
# for kw in kw_list
|
|
||||||
# @show typeof((kw[:x], kw[:y], kw[:z]))
|
|
||||||
# end
|
|
||||||
|
|
||||||
# this is it folks!
|
# this is it folks!
|
||||||
# TODO: we probably shouldn't use i for tracking series index, but rather explicitly track it in recipes
|
# TODO: we probably shouldn't use i for tracking series index, but rather explicitly track it in recipes
|
||||||
for (i,kw) in enumerate(kw_list)
|
for (i,kw) in enumerate(kw_list)
|
||||||
# DD(kw, "series $i before")
|
|
||||||
if !(get(kw, :seriestype, :none) in (:xerror, :yerror))
|
if !(get(kw, :seriestype, :none) in (:xerror, :yerror))
|
||||||
plt.n += 1
|
plt.n += 1
|
||||||
end
|
end
|
||||||
@ -309,16 +268,10 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
sp.attr[:annotations] = vcat(sp_anns, anns)
|
sp.attr[:annotations] = vcat(sp_anns, anns)
|
||||||
|
|
||||||
# we update subplot args in case something like the color palatte is part of the recipe
|
# we update subplot args in case something like the color palatte is part of the recipe
|
||||||
# DD(sp.attr[:xaxis].d, "before USA $i")
|
|
||||||
# DD(kw, "kw")
|
|
||||||
_update_subplot_args(plt, sp, kw, idx)
|
_update_subplot_args(plt, sp, kw, idx)
|
||||||
# DD(sp.attr[:xaxis].d, "after USA $i")
|
|
||||||
|
|
||||||
# set default values, select from attribute cycles, and generally set the final attributes
|
# set default values, select from attribute cycles, and generally set the final attributes
|
||||||
_add_defaults!(kw, plt, sp, i)
|
_add_defaults!(kw, plt, sp, i)
|
||||||
# DD(kw, "series $i after")
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
# now we have a fully specified series, with colors chosen. we must recursively handle
|
# now we have a fully specified series, with colors chosen. we must recursively handle
|
||||||
# series recipes, which dispatch on seriestype. If a backend does not natively support a seriestype,
|
# series recipes, which dispatch on seriestype. If a backend does not natively support a seriestype,
|
||||||
@ -326,14 +279,9 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
# For example, a histogram is just a bar plot with binned data, a bar plot is really a filled step plot,
|
# For example, a histogram is just a bar plot with binned data, a bar plot is really a filled step plot,
|
||||||
# and a step plot is really just a path. So any backend that supports drawing a path will implicitly
|
# and a step plot is really just a path. So any backend that supports drawing a path will implicitly
|
||||||
# be able to support step, bar, and histogram plots (and any recipes that use those components).
|
# be able to support step, bar, and histogram plots (and any recipes that use those components).
|
||||||
# DD(sp.attr[:xaxis].d, "before $i")
|
|
||||||
_apply_series_recipe(plt, kw)
|
_apply_series_recipe(plt, kw)
|
||||||
# DD(sp.attr[:xaxis].d, "after $i")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# # now that we're done adding all the series, add the annotations
|
|
||||||
# _add_annotations(plt, anns)
|
|
||||||
|
|
||||||
# TODO just need to pass plt... and we should do all non-series updates here
|
# TODO just need to pass plt... and we should do all non-series updates here
|
||||||
_update_plot(plt, plt.plotargs)
|
_update_plot(plt, plt.plotargs)
|
||||||
|
|
||||||
@ -348,18 +296,6 @@ function _plot!(plt::Plot, d::KW, args...)
|
|||||||
plt
|
plt
|
||||||
end
|
end
|
||||||
|
|
||||||
# # handle the grouping
|
|
||||||
# function _add_series(plt::Plot, d::KW, groupby::GroupBy, args...)
|
|
||||||
# starting_n = plt.n
|
|
||||||
# for (i, glab) in enumerate(groupby.groupLabels)
|
|
||||||
# tmpd = copy(d)
|
|
||||||
# tmpd[:numUncounted] = plt.n - starting_n
|
|
||||||
# _add_series(plt, tmpd, nothing, args...;
|
|
||||||
# idxfilter = groupby.groupIds[i],
|
|
||||||
# grouplabel = string(glab))
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
|
|
||||||
function _replace_linewidth(d::KW)
|
function _replace_linewidth(d::KW)
|
||||||
# get a good default linewidth... 0 for surface and heatmaps
|
# get a good default linewidth... 0 for surface and heatmaps
|
||||||
@ -368,63 +304,6 @@ function _replace_linewidth(d::KW)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# # no grouping
|
|
||||||
# function _add_series(plt::Plot, d::KW, args...;
|
|
||||||
# idxfilter = nothing,
|
|
||||||
# grouplabel = "")
|
|
||||||
#
|
|
||||||
# # get the list of dictionaries, one per series
|
|
||||||
# dumpdict(d, "before process_inputs")
|
|
||||||
# process_inputs(plt, d, args...)
|
|
||||||
# dumpdict(d, "after process_inputs")
|
|
||||||
#
|
|
||||||
# if idxfilter != nothing
|
|
||||||
# # add the group name as the label if there isn't one passed in
|
|
||||||
# get!(d, :label, grouplabel)
|
|
||||||
# # filter the data
|
|
||||||
# filter_data!(d, idxfilter)
|
|
||||||
# end
|
|
||||||
# # dumpdict(d,"",true)
|
|
||||||
#
|
|
||||||
# seriesArgList, xmeta, ymeta = build_series_args(plt, d) #, idxfilter)
|
|
||||||
# # seriesArgList, xmeta, ymeta = build_series_args(plt, groupargs..., args...; d...)
|
|
||||||
#
|
|
||||||
# # # if we were able to extract guide information from the series inputs, then update the plot
|
|
||||||
# # # @show xmeta, ymeta
|
|
||||||
# # updateDictWithMeta(d, plt.plotargs, xmeta, true)
|
|
||||||
# # updateDictWithMeta(d, plt.plotargs, ymeta, false)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# # function _add_series(plt::Plot, ds::)
|
|
||||||
# # now we can plot the series
|
|
||||||
# for (i,di) in enumerate(seriesArgList)
|
|
||||||
# plt.n += 1
|
|
||||||
#
|
|
||||||
# if !stringsSupported() && di[:seriestype] != :pie
|
|
||||||
# setTicksFromStringVector(plt, d, di, "x")
|
|
||||||
# setTicksFromStringVector(plt, d, di, "y")
|
|
||||||
# setTicksFromStringVector(plt, d, di, "z")
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# # remove plot args
|
|
||||||
# for k in keys(_plot_defaults)
|
|
||||||
# delete!(di, k)
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# # merge in plotarg_overrides
|
|
||||||
# plotarg_overrides = pop!(di, :plotarg_overrides, nothing)
|
|
||||||
# if plotarg_overrides != nothing
|
|
||||||
# merge!(plt.plotargs, plotarg_overrides)
|
|
||||||
# end
|
|
||||||
# # dumpdict(plt.plotargs, "pargs", true)
|
|
||||||
#
|
|
||||||
# dumpdict(di, "Series $i")
|
|
||||||
#
|
|
||||||
# _replace_linewidth(di)
|
|
||||||
#
|
|
||||||
# _add_series(plt.backend, plt, di)
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
@ -482,54 +361,11 @@ end
|
|||||||
# end
|
# end
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
|
||||||
|
|
||||||
# TODO: remove
|
|
||||||
# # should we update the x/y label given the meta info during input slicing?
|
|
||||||
# function updateDictWithMeta(d::KW, plotargs::KW, meta::Symbol, isx::Bool)
|
|
||||||
# lsym = isx ? :xguide : :yguide
|
|
||||||
# if plotargs[lsym] == default(lsym)
|
|
||||||
# d[lsym] = string(meta)
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# updateDictWithMeta(d::KW, plotargs::KW, meta, isx::Bool) = nothing
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|
||||||
annotations(::Void) = []
|
annotations(::Void) = []
|
||||||
annotations(anns::AVec) = anns
|
annotations(anns::AVec) = anns
|
||||||
annotations(anns) = Any[anns]
|
annotations(anns) = Any[anns]
|
||||||
# annotations{X,Y,V}(v::AVec{@compat(Tuple{X,Y,V})}) = v
|
|
||||||
# annotations{X,Y,V}(t::@compat(Tuple{X,Y,V})) = [t]
|
|
||||||
# annotations(v::AVec{PlotText}) = v
|
|
||||||
# annotations(v::AVec) = map(PlotText, v)
|
|
||||||
# annotations(anns) = error("Expecting a tuple (or vector of tuples) for annotations: ",
|
|
||||||
# "(x, y, annotation)\n got: $(typeof(anns))")
|
|
||||||
|
|
||||||
# function annotations(plt::Plot, anns)
|
|
||||||
# anns = annotations(anns)
|
|
||||||
# # if we just have a list of PlotText objects, then create (x,y,text) tuples
|
|
||||||
# if typeof(anns) <: AVec{PlotText}
|
|
||||||
# x, y = plt[plt.n]
|
|
||||||
# anns = Tuple{Float64,Float64,PlotText}[(x[i], y[i], t) for (i,t) in enumerate(anns)]
|
|
||||||
# end
|
|
||||||
# anns
|
|
||||||
# end
|
|
||||||
|
|
||||||
|
|
||||||
# function _add_annotations(plt::Plot, d::KW)
|
|
||||||
# anns = annotations(get(d, :annotation, nothing))
|
|
||||||
# if !isempty(anns)
|
|
||||||
#
|
|
||||||
# # if we just have a list of PlotText objects, then create (x,y,text) tuples
|
|
||||||
# if typeof(anns) <: AVec{PlotText}
|
|
||||||
# x, y = plt[plt.n]
|
|
||||||
# anns = Tuple{Float64,Float64,PlotText}[(x[i], y[i], t) for (i,t) in enumerate(anns)]
|
|
||||||
# end
|
|
||||||
#
|
|
||||||
# _add_annotations(plt, anns)
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
|
|||||||
@ -1,7 +1,15 @@
|
|||||||
|
|
||||||
|
|
||||||
function Subplot{T<:AbstractBackend}(::T; parent = RootLayout())
|
function Subplot{T<:AbstractBackend}(::T; parent = RootLayout())
|
||||||
Subplot{T}(parent, defaultbox, defaultbox, KW(), nothing, nothing)
|
Subplot{T}(
|
||||||
|
parent,
|
||||||
|
(20mm, 5mm, 2mm, 10mm),
|
||||||
|
defaultbox,
|
||||||
|
defaultbox,
|
||||||
|
KW(),
|
||||||
|
nothing,
|
||||||
|
nothing
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
plotarea!(sp::Subplot, bbox::BoundingBox) = (sp.plotarea = bbox)
|
plotarea!(sp::Subplot, bbox::BoundingBox) = (sp.plotarea = bbox)
|
||||||
@ -11,6 +19,10 @@ Base.size(sp::Subplot) = (1,1)
|
|||||||
Base.length(sp::Subplot) = 1
|
Base.length(sp::Subplot) = 1
|
||||||
Base.getindex(sp::Subplot, r::Int, c::Int) = sp
|
Base.getindex(sp::Subplot, r::Int, c::Int) = sp
|
||||||
|
|
||||||
|
leftpad(sp::Subplot) = sp.minpad[1]
|
||||||
|
toppad(sp::Subplot) = sp.minpad[2]
|
||||||
|
rightpad(sp::Subplot) = sp.minpad[3]
|
||||||
|
bottompad(sp::Subplot) = sp.minpad[4]
|
||||||
|
|
||||||
get_subplot(plt::Plot, sp::Subplot) = sp
|
get_subplot(plt::Plot, sp::Subplot) = sp
|
||||||
get_subplot(plt::Plot, i::Integer) = plt.subplots[i]
|
get_subplot(plt::Plot, i::Integer) = plt.subplots[i]
|
||||||
|
|||||||
@ -32,6 +32,7 @@ end
|
|||||||
# a single subplot
|
# a single subplot
|
||||||
type Subplot{T<:AbstractBackend} <: AbstractLayout
|
type Subplot{T<:AbstractBackend} <: AbstractLayout
|
||||||
parent::AbstractLayout
|
parent::AbstractLayout
|
||||||
|
minpad::Tuple # leftpad, toppad, rightpad, bottompad
|
||||||
bbox::BoundingBox # the canvas area which is available to this subplot
|
bbox::BoundingBox # the canvas area which is available to this subplot
|
||||||
plotarea::BoundingBox # the part where the data goes
|
plotarea::BoundingBox # the part where the data goes
|
||||||
attr::KW # args specific to this subplot
|
attr::KW # args specific to this subplot
|
||||||
|
|||||||
40
src/utils.jl
40
src/utils.jl
@ -481,14 +481,44 @@ function getxyz(plt::Plot, i::Integer)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function setxy!{X,Y}(plt::Plot, xy::Tuple{X,Y}, i::Integer)
|
function setxy!{X,Y}(plt::Plot, xy::Tuple{X,Y}, i::Integer)
|
||||||
d = plt.series_list[i].d
|
series = plt.series_list[i]
|
||||||
d[:x], d[:y] = xy
|
series.d[:x], series.d[:y] = xy
|
||||||
|
_series_updated(plt, series)
|
||||||
end
|
end
|
||||||
function setxyz!{X,Y,Z}(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer)
|
function setxyz!{X,Y,Z}(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer)
|
||||||
d = plt.series_list[i].d
|
series = plt.series_list[i]
|
||||||
d[:x], d[:y], d[:z] = xyz
|
series.d[:x], series.d[:y], series.d[:z] = xyz
|
||||||
|
_series_updated(plt, series)
|
||||||
end
|
end
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# function setxy!{X,Y}(plt::Plot{PyPlotBackend}, xy::Tuple{X,Y}, i::Integer)
|
||||||
|
# series = plt.series_list[i]
|
||||||
|
# d = series.d
|
||||||
|
# d[:x], d[:y] = xy
|
||||||
|
# for handle in d[:serieshandle]
|
||||||
|
# try
|
||||||
|
# handle[:set_data](xy...)
|
||||||
|
# catch
|
||||||
|
# handle[:set_offsets](hcat(xy...))
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# update_limits!(d[:subplot], series, (:x,:y))
|
||||||
|
# plt
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# function setxyz!{X,Y,Z}(plt::Plot{PyPlotBackend}, xyz::Tuple{X,Y,Z}, i::Integer)
|
||||||
|
# series = plt.series_list[i]
|
||||||
|
# d = series.d
|
||||||
|
# d[:x], d[:y], d[:z] = xyz
|
||||||
|
# for handle in d[:serieshandle]
|
||||||
|
# handle[:set_data](d[:x], d[:y])
|
||||||
|
# handle[:set_3d_properties](d[:z])
|
||||||
|
# end
|
||||||
|
# update_limits!(d[:subplot], series, (:x,:y,:z))
|
||||||
|
# plt
|
||||||
|
# end
|
||||||
|
|
||||||
# -------------------------------------------------------
|
# -------------------------------------------------------
|
||||||
# indexing notation
|
# indexing notation
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user