inset_subplots; GR log axes fix
This commit is contained in:
parent
3b33b054d3
commit
266d2efde5
@ -19,6 +19,8 @@ export
|
||||
GridLayout,
|
||||
grid,
|
||||
EmptyLayout,
|
||||
bbox,
|
||||
plotarea,
|
||||
@layout,
|
||||
AVec,
|
||||
AMat,
|
||||
|
||||
@ -60,6 +60,7 @@ const _arg_desc = KW(
|
||||
:link => "Symbol. How/whether to link axis limits between subplots. Values: `:none`, `:x` (x axes are linked by columns), `:y` (y axes are linked by rows), `:both` (x and y are linked), `:all` (every subplot is linked together regardless of layout position).",
|
||||
:overwrite_figure => "Bool. Should we reuse the same GUI window/figure when plotting (true) or open a new one (false).",
|
||||
:html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.",
|
||||
:inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots",
|
||||
|
||||
# subplot args
|
||||
:title => "String. Subplot title.",
|
||||
|
||||
@ -198,6 +198,8 @@ const _plot_defaults = KW(
|
||||
:link => :none,
|
||||
:overwrite_figure => true,
|
||||
:html_output_format => :auto,
|
||||
:inset_subplots => nothing, # optionally pass a vector of (parent,bbox) tuples which are
|
||||
# the parent layout and the relative bounding box of inset subplots
|
||||
)
|
||||
|
||||
|
||||
@ -256,6 +258,7 @@ const _suppress_warnings = Set{Symbol}([
|
||||
:plot_object,
|
||||
:primary,
|
||||
:smooth,
|
||||
:relative_bbox,
|
||||
])
|
||||
|
||||
# add defaults for the letter versions
|
||||
|
||||
@ -576,8 +576,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
|
||||
|
||||
x1, x2 = xaxis[:flip] ? (xmax,xmin) : (xmin,xmax)
|
||||
y1, y2 = yaxis[:flip] ? (ymax,ymin) : (ymin,ymax)
|
||||
GR.axes(xtick, ytick, x1, y1, majorx, majory, ticksize)
|
||||
GR.axes(xtick, ytick, x2, y2, -majorx, -majory, -ticksize)
|
||||
GR.axes(xtick, ytick, x1, y1, 1, 1, ticksize)
|
||||
GR.axes(xtick, ytick, x2, y2, -1, -1, -ticksize)
|
||||
end
|
||||
# end
|
||||
|
||||
|
||||
@ -101,6 +101,9 @@ end
|
||||
|
||||
Base.show(io::IO, layout::AbstractLayout) = print(io, "$(typeof(layout))$(size(layout))")
|
||||
|
||||
# create a new bbox
|
||||
bbox(left, top, w, h) = BoundingBox(left, top, w, h)
|
||||
|
||||
# this is the available area for drawing everything in this layout... as percentages of total canvas
|
||||
bbox(layout::AbstractLayout) = layout.bbox
|
||||
bbox!(layout::AbstractLayout, bb::BoundingBox) = (layout.bbox = bb)
|
||||
@ -116,8 +119,12 @@ parent_bbox(layout::AbstractLayout) = bbox(parent(layout))
|
||||
update_position!(layout::AbstractLayout) = nothing
|
||||
update_child_bboxes!(layout::AbstractLayout, minimum_perimeter = [0mm,0mm,0mm,0mm]) = nothing
|
||||
|
||||
width(layout::AbstractLayout) = width(layout.bbox)
|
||||
height(layout::AbstractLayout) = height(layout.bbox)
|
||||
left(layout::AbstractLayout) = left(bbox(layout))
|
||||
top(layout::AbstractLayout) = top(bbox(layout))
|
||||
right(layout::AbstractLayout) = right(bbox(layout))
|
||||
bottom(layout::AbstractLayout) = bottom(bbox(layout))
|
||||
width(layout::AbstractLayout) = width(bbox(layout))
|
||||
height(layout::AbstractLayout) = height(bbox(layout))
|
||||
|
||||
plotarea(layout::AbstractLayout) = defaultbox
|
||||
plotarea!(layout::AbstractLayout, bbox::BoundingBox) = nothing
|
||||
@ -335,6 +342,26 @@ function update_child_bboxes!(layout::GridLayout, minimum_perimeter = [0mm,0mm,0
|
||||
end
|
||||
end
|
||||
|
||||
function update_inset_bboxes!(plt::Plot)
|
||||
for sp in plt.inset_subplots
|
||||
relative_bbox = sp[:relative_bbox]
|
||||
# TODO: need to handle percentages... right now only AbsoluteLength works
|
||||
|
||||
bb = bbox!(sp, bbox(
|
||||
left(sp.parent) + left(relative_bbox),
|
||||
top(sp.parent) + top(relative_bbox),
|
||||
width(relative_bbox),
|
||||
height(relative_bbox)
|
||||
))
|
||||
|
||||
plotarea!(sp, bbox(
|
||||
left(bb) + leftpad(sp),
|
||||
top(bb) + toppad(sp),
|
||||
width(bb) - leftpad(sp) - rightpad(sp),
|
||||
height(bb) - toppad(sp) - bottompad(sp)
|
||||
))
|
||||
end
|
||||
end
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
||||
27
src/plot.jl
27
src/plot.jl
@ -350,6 +350,27 @@ function _plot!(plt::Plot, d::KW, args...)
|
||||
sp.attr[:subplot_index] = idx
|
||||
end
|
||||
|
||||
# handle inset subplots
|
||||
insets = plt[:inset_subplots]
|
||||
if insets != nothing
|
||||
for (parent, bb) in insets
|
||||
P = typeof(parent)
|
||||
if P <: Integer
|
||||
parent = plt.subplots[parent]
|
||||
elseif P == Symbol
|
||||
parent = plt.spmap[parent]
|
||||
else
|
||||
parent = plt.layout
|
||||
end
|
||||
sp = Subplot(backend(), parent=parent)
|
||||
sp.plt = plt
|
||||
sp.attr[:relative_bbox] = bb
|
||||
push!(plt.subplots, sp)
|
||||
sp.attr[:subplot_index] = length(plt.subplots)
|
||||
push!(plt.inset_subplots, sp)
|
||||
end
|
||||
end
|
||||
|
||||
plt.init = true
|
||||
end
|
||||
|
||||
@ -440,10 +461,16 @@ function prepare_output(plt::Plot)
|
||||
# One pass down and back up the tree to compute the minimum padding
|
||||
# of the children on the perimeter. This is an backend callback.
|
||||
_update_min_padding!(plt.layout)
|
||||
for sp in plt.inset_subplots
|
||||
_update_min_padding!(sp)
|
||||
end
|
||||
|
||||
# now another pass down, to update the bounding boxes
|
||||
update_child_bboxes!(plt.layout)
|
||||
|
||||
# update those bounding boxes of inset subplots
|
||||
update_inset_bboxes!(plt)
|
||||
|
||||
# the backend callback, to reposition subplots, etc
|
||||
_update_plot_object(plt)
|
||||
end
|
||||
|
||||
@ -73,12 +73,14 @@ type Plot{T<:AbstractBackend} <: AbstractPlot{T}
|
||||
subplots::Vector{Subplot}
|
||||
spmap::SubplotMap # provide any label as a map to a subplot
|
||||
layout::AbstractLayout
|
||||
inset_subplots::Vector{Subplot} # list of inset subplots
|
||||
init::Bool
|
||||
end
|
||||
|
||||
function Plot()
|
||||
Plot(backend(), 0, KW(), KW(), Series[], nothing,
|
||||
Subplot[], SubplotMap(), EmptyLayout(), false)
|
||||
Subplot[], SubplotMap(), EmptyLayout(),
|
||||
Subplot[], false)
|
||||
end
|
||||
|
||||
# TODO: make a decision... should plt[1] return the first subplot or the first series??
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user