Skip to content

Commit

Permalink
First pass at an auto-layout
Browse files Browse the repository at this point in the history
  • Loading branch information
BioTurboNick committed Jun 10, 2022
1 parent 6266ff8 commit 5fafc16
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/args.jl
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ const _plot_defaults = KW(
:thickness_scaling => 1,
:display_type => :auto,
:warn_on_unsupported => true,
:plotarea => :auto,
:extra_plot_kwargs => Dict(),
:extra_kwargs => :series, # directs collection of extra_kwargs
)
Expand Down
42 changes: 41 additions & 1 deletion src/layouts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,9 @@ end

layout_args(n_override::Integer, layout::Union{AbstractVecOrMat,GridLayout}) =
layout_args(layout)

layout_args(n_override::Integer, mode::Symbol) =
mode === :auto ? (mode, n_override) : error("unhandled layout mode $(typeof(mode)): $mode") # pass-through mode
layout_args(mode::Symbol) = mode === :auto ? (mode, 1) : error("unhandled layout mode $(typeof(mode)): $mode") # pass-through mode
layout_args(huh) = error("unhandled layout type $(typeof(huh)): $huh")

# ----------------------------------------------------------------------
Expand Down Expand Up @@ -579,6 +581,44 @@ function build_layout(layout::GridLayout, n::Integer, plts::AVec{Plot})
layout, subplots, spmap
end

# handle :auto mode, which produces a series of subplots in a square as large as necessary to accomodate them.
function build_layout(layout::Symbol, n::Integer, plts::AVec{Plot})
layout === :auto || error("Unrecognized layout mode: $layout")

# step 1: collect minimum sizes for each subplot or apply a default if unspecified
minsizes = Vector{Union{Symbol, Tuple{Float64, Float64}}}(undef, length(plts))
minsizes .= get.(plts, :plotarea, Ref((150.0, 150.0)))
minsizes[minsizes .== :auto] .= Ref((150.0, 150.0))

plotcountx = Int(round(sqrt(length(plts))))
plotcounty = Int(ceil(length(plts) / plotcountx))

# compute the total size
plotwidth = 0.0
plotrowwidth = 0.0
plotrowheight = 0.0
plotheight = 0.0
xcount = 1
for i eachindex(minsizes)
plotrowwidth += minsizes[i][1]
plotrowheight = max(plotrowheight, minsizes[i][2])
if xcount == plotcountx
xcount = 1
plotheight += plotrowheight
plotwidth = max(plotwidth, plotrowwidth)
plotrowheight = 0.0
plotrowwidth = 0.0
else
xcount += 1
end
end

layout = GridLayout(plotcounty, plotcountx)
layout.attr[:width] = plotwidth
layout.attr[:height] = plotheight
build_layout(layout, n, plts)
end

# -------------------------------------------------------------------------

# make all reference the same axis extrema/values.
Expand Down
8 changes: 8 additions & 0 deletions src/plot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ function plot!(plt1::Plot, plt2::Plot, plts_tail::Plot...; kw...)

# create the layout
plt.layout, plt.subplots, plt.spmap = build_layout(layout, num_sp, copy(plts))
if layout === :auto
if plt.attr[:size][1] < plt.layout.attr[:width]
plt.attr[:size] = (plt.layout.attr[:width], plt.attr[:size][2])
end
if plt.attr[:size][2] < plt.layout.attr[:height]
plt.attr[:size] = (plt.attr[:size][1], plt.layout.attr[:height])
end
end

# do we need to link any axes together?
link_axes!(plt.layout, plt[:link])
Expand Down

0 comments on commit 5fafc16

Please sign in to comment.