colorbar layout fixes; process_axis_arg and related fix
This commit is contained in:
parent
862ac3af8a
commit
4a96122067
43
src/args.jl
43
src/args.jl
@ -613,26 +613,29 @@ end
|
|||||||
function preprocessArgs!(d::KW)
|
function preprocessArgs!(d::KW)
|
||||||
replaceAliases!(d, _keyAliases)
|
replaceAliases!(d, _keyAliases)
|
||||||
|
|
||||||
# # handle axis args
|
# handle axis args
|
||||||
# for letter in ("x", "y", "z")
|
for letter in (:x, :y, :z)
|
||||||
# asym = symbol(letter * "axis")
|
asym = symbol(letter, :axis)
|
||||||
# for arg in wraptuple(pop!(d, asym, ()))
|
args = pop!(d, asym, ())
|
||||||
# processAxisArg(d, letter, arg)
|
if !(typeof(args) <: Axis)
|
||||||
# end
|
for arg in wraptuple(args)
|
||||||
# # delete!(d, asym)
|
process_axis_arg!(d, arg, letter)
|
||||||
#
|
end
|
||||||
# # # NOTE: this logic was moved to _add_plotargs...
|
end
|
||||||
# # # turn :labels into :ticks_and_labels
|
# delete!(d, asym)
|
||||||
# # tsym = symbol(letter * "ticks")
|
|
||||||
# # if haskey(d, tsym) && ticksType(d[tsym]) == :labels
|
# # NOTE: this logic was moved to _add_plotargs...
|
||||||
# # d[tsym] = (1:length(d[tsym]), d[tsym])
|
# # turn :labels into :ticks_and_labels
|
||||||
# # end
|
# tsym = symbol(letter * "ticks")
|
||||||
# #
|
# if haskey(d, tsym) && ticksType(d[tsym]) == :labels
|
||||||
# # ssym = symbol(letter * "scale")
|
# d[tsym] = (1:length(d[tsym]), d[tsym])
|
||||||
# # if haskey(d, ssym) && haskey(_scaleAliases, d[ssym])
|
# end
|
||||||
# # d[ssym] = _scaleAliases[d[ssym]]
|
#
|
||||||
# # end
|
# ssym = symbol(letter * "scale")
|
||||||
# end
|
# if haskey(d, ssym) && haskey(_scaleAliases, d[ssym])
|
||||||
|
# d[ssym] = _scaleAliases[d[ssym]]
|
||||||
|
# end
|
||||||
|
end
|
||||||
|
|
||||||
# # if title is just a single string, then assume we want plot_title
|
# # if title is just a single string, then assume we want plot_title
|
||||||
# # TODO: make a decision if this is correct
|
# # TODO: make a decision if this is correct
|
||||||
|
|||||||
74
src/axes.jl
74
src/axes.jl
@ -21,46 +21,50 @@ function Axis(letter::Symbol, args...; kw...)
|
|||||||
update!(Axis(d), args...; kw...)
|
update!(Axis(d), args...; kw...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function process_axis_arg!(d::KW, arg, letter = "")
|
||||||
|
T = typeof(arg)
|
||||||
|
arg = get(_scaleAliases, arg, arg)
|
||||||
|
|
||||||
|
if typeof(arg) <: Font
|
||||||
|
d[symbol(letter,:tickfont)] = arg
|
||||||
|
d[symbol(letter,:guidefont)] = arg
|
||||||
|
|
||||||
|
elseif arg in _allScales
|
||||||
|
d[symbol(letter,:scale)] = arg
|
||||||
|
|
||||||
|
elseif arg in (:flip, :invert, :inverted)
|
||||||
|
d[symbol(letter,:flip)] = true
|
||||||
|
|
||||||
|
elseif T <: @compat(AbstractString)
|
||||||
|
d[symbol(letter,:guide)] = arg
|
||||||
|
|
||||||
|
# xlims/ylims
|
||||||
|
elseif (T <: Tuple || T <: AVec) && length(arg) == 2
|
||||||
|
sym = typeof(arg[1]) <: Number ? :lims : :ticks
|
||||||
|
d[symbol(letter,sym)] = arg
|
||||||
|
|
||||||
|
# xticks/yticks
|
||||||
|
elseif T <: AVec
|
||||||
|
d[symbol(letter,:ticks)] = arg
|
||||||
|
|
||||||
|
elseif arg == nothing
|
||||||
|
d[symbol(letter,:ticks)] = []
|
||||||
|
|
||||||
|
elseif typeof(arg) <: Number
|
||||||
|
d[symbol(letter,:rotation)] = arg
|
||||||
|
|
||||||
|
else
|
||||||
|
warn("Skipped $(letter)axis arg $arg")
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# update an Axis object with magic args and keywords
|
# update an Axis object with magic args and keywords
|
||||||
function update!(a::Axis, args...; kw...)
|
function update!(a::Axis, args...; kw...)
|
||||||
# first process args
|
# first process args
|
||||||
d = a.d
|
d = a.d
|
||||||
for arg in args
|
for arg in args
|
||||||
T = typeof(arg)
|
process_axis_arg!(d, arg)
|
||||||
arg = get(_scaleAliases, arg, arg)
|
|
||||||
|
|
||||||
if typeof(arg) <: Font
|
|
||||||
d[:tickfont] = arg
|
|
||||||
d[:guidefont] = arg
|
|
||||||
|
|
||||||
elseif arg in _allScales
|
|
||||||
d[:scale] = arg
|
|
||||||
|
|
||||||
elseif arg in (:flip, :invert, :inverted)
|
|
||||||
d[:flip] = true
|
|
||||||
|
|
||||||
elseif T <: @compat(AbstractString)
|
|
||||||
d[:guide] = arg
|
|
||||||
|
|
||||||
# xlims/ylims
|
|
||||||
elseif (T <: Tuple || T <: AVec) && length(arg) == 2
|
|
||||||
sym = typeof(arg[1]) <: Number ? :lims : :ticks
|
|
||||||
d[sym] = arg
|
|
||||||
|
|
||||||
# xticks/yticks
|
|
||||||
elseif T <: AVec
|
|
||||||
d[:ticks] = arg
|
|
||||||
|
|
||||||
elseif arg == nothing
|
|
||||||
d[:ticks] = []
|
|
||||||
|
|
||||||
elseif typeof(arg) <: Number
|
|
||||||
d[:rotation] = arg
|
|
||||||
|
|
||||||
else
|
|
||||||
warn("Skipped $(letter)axis arg $arg")
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# then override for any keywords... only those keywords that already exists in d
|
# then override for any keywords... only those keywords that already exists in d
|
||||||
|
|||||||
@ -267,22 +267,31 @@ function py_bbox(obj)
|
|||||||
BoundingBox(l*px, (ft-t)*px, (r-l)*px, (t-b)*px)
|
BoundingBox(l*px, (ft-t)*px, (r-l)*px, (t-b)*px)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# get the bounding box of the union of the objects
|
||||||
|
function py_bbox(v::AVec)
|
||||||
|
bbox_union = defaultbox
|
||||||
|
for obj in v
|
||||||
|
bbox_union = bbox_union + py_bbox(obj)
|
||||||
|
end
|
||||||
|
bbox_union
|
||||||
|
end
|
||||||
|
|
||||||
function py_bbox_ticks(ax, letter)
|
function py_bbox_ticks(ax, letter)
|
||||||
# fig = ax[:get_figure]()
|
# fig = ax[:get_figure]()
|
||||||
# @show fig
|
# @show fig
|
||||||
labels = ax[symbol("get_"*letter*"ticklabels")]()
|
labels = ax[symbol("get_"*letter*"ticklabels")]()
|
||||||
# @show labels
|
py_bbox(labels)
|
||||||
# bboxes = []
|
# # @show labels
|
||||||
bbox_union = defaultbox
|
# # bboxes = []
|
||||||
for lab in labels
|
# bbox_union = defaultbox
|
||||||
# @show lab,lab[:get_text]()
|
# for lab in labels
|
||||||
bbox = py_bbox(lab)
|
# # @show lab,lab[:get_text]()
|
||||||
bbox_union = bbox_union + bbox
|
# bbox = py_bbox(lab)
|
||||||
# @show letter,bbox bbox_union
|
# bbox_union = bbox_union + bbox
|
||||||
# @show bbox_union
|
# # @show letter,bbox bbox_union
|
||||||
end
|
# # @show bbox_union
|
||||||
bbox_union
|
# end
|
||||||
|
# bbox_union
|
||||||
end
|
end
|
||||||
|
|
||||||
function py_bbox_axislabel(ax, letter)
|
function py_bbox_axislabel(ax, letter)
|
||||||
@ -316,6 +325,8 @@ min_padding_top(layout::Subplot{PyPlotBackend}) = compute_min_padding(layout,
|
|||||||
min_padding_right(layout::Subplot{PyPlotBackend}) = compute_min_padding(layout, right, -1)
|
min_padding_right(layout::Subplot{PyPlotBackend}) = compute_min_padding(layout, right, -1)
|
||||||
min_padding_bottom(layout::Subplot{PyPlotBackend}) = compute_min_padding(layout, bottom,-1)
|
min_padding_bottom(layout::Subplot{PyPlotBackend}) = compute_min_padding(layout, bottom,-1)
|
||||||
|
|
||||||
|
const _cbar_width = 5mm
|
||||||
|
|
||||||
# loop over the guides and axes and compute how far they "stick out" from the plot area,
|
# loop over the guides and axes and compute how far they "stick out" from the plot area,
|
||||||
# so that we know the minimum padding we need to avoid cropping and overlapping text.
|
# so that we know the minimum padding we need to avoid cropping and overlapping text.
|
||||||
# `func` is one of (left,top,right,bottom), and we multiply by 1 or -1 depending on direction
|
# `func` is one of (left,top,right,bottom), and we multiply by 1 or -1 depending on direction
|
||||||
@ -337,6 +348,14 @@ function compute_min_padding(sp::Subplot{PyPlotBackend}, func::Function, mult::N
|
|||||||
# @show padding
|
# @show padding
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if func == right && haskey(sp.attr, :cbar_ax)
|
||||||
|
# TODO: need bounding box of colorbar labels
|
||||||
|
# bb = py_bbox(sp.attr[:cbar_ax][:get_ticklabels]())
|
||||||
|
bb = BoundingBox(0mm,0mm,15mm,15mm)
|
||||||
|
sp.attr[:cbar_width] = _cbar_width + width(bb)
|
||||||
|
padding = padding + sp.attr[:cbar_width]
|
||||||
|
end
|
||||||
|
|
||||||
# if func == top
|
# if func == top
|
||||||
# titlebbox = py_bbox_title(ax)
|
# titlebbox = py_bbox_title(ax)
|
||||||
# padding = max(padding, height(titlebbox))
|
# padding = max(padding, height(titlebbox))
|
||||||
@ -374,24 +393,47 @@ end
|
|||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# TODO: add this (and _cbar_width) to layouts.jl?
|
||||||
|
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 update_position!(sp::Subplot{PyPlotBackend})
|
function update_position!(sp::Subplot{PyPlotBackend})
|
||||||
ax = sp.o
|
ax = sp.o
|
||||||
ax == nothing && return
|
ax == nothing && return
|
||||||
figw, figh = size(py_bbox_fig(sp.plt))
|
figw, figh = size(py_bbox_fig(sp.plt))
|
||||||
|
|
||||||
# plot_bb = plotarea_bbox(sp)
|
# plot_bb = plotarea_bbox(sp)
|
||||||
plot_bb = sp.plotarea
|
# plot_bb = sp.plotarea
|
||||||
# @show sp.bbox plot_bb
|
# @show sp.bbox plot_bb
|
||||||
# l = float(left(plot_bb) / px) / figw
|
# l = float(left(plot_bb) / px) / figw
|
||||||
# b = float(bottom(plot_bb) / px) / figh
|
# b = float(bottom(plot_bb) / px) / figh
|
||||||
# w = float(width(plot_bb) / px) / figw
|
# w = float(width(plot_bb) / px) / figw
|
||||||
mms = Float64[f(plot_bb).value for f in (left, bottom, width, height)]
|
# mms = Float64[f(plot_bb).value for f in (left, bottom, width, height)]
|
||||||
|
#
|
||||||
mms[2] = figh.value - mms[2]
|
# mms[2] = figh.value - mms[2]
|
||||||
# @show mms
|
# # @show mms
|
||||||
pcts = mms ./ Float64[figw.value, figh.value, figw.value, figh.value]
|
# pcts = mms ./ Float64[figw.value, figh.value, figw.value, figh.value]
|
||||||
|
pcts = bbox_to_pcts(sp.plotarea, figw, figh)
|
||||||
# @show pcts
|
# @show pcts
|
||||||
ax[:set_position](pcts)
|
ax[:set_position](pcts)
|
||||||
|
|
||||||
|
# set the cbar position if there is one
|
||||||
|
# @show sp.attr[:cbar_ax]
|
||||||
|
if haskey(sp.attr, :cbar_ax)
|
||||||
|
cbw = sp.attr[:cbar_width]
|
||||||
|
# cb_bbox = BoundingBox(figw - cbw, 0.1figh, cbw, figh - 0.2pct)
|
||||||
|
# this is the bounding box of just the colors of the colorbar (not labels)
|
||||||
|
cb_bbox = BoundingBox(right(sp.bbox)-cbw+2mm, top(sp.bbox)+2mm, _cbar_width, height(sp.bbox)-4mm)
|
||||||
|
pcts = bbox_to_pcts(cb_bbox, figw, figh)
|
||||||
|
# @show cbw cb_bbox pcts
|
||||||
|
sp.attr[:cbar_ax][:set_position](pcts)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# each backend should set up the subplot here
|
# each backend should set up the subplot here
|
||||||
@ -935,24 +977,40 @@ function _add_series(plt::Plot{PyPlotBackend}, series::Series)
|
|||||||
handleSmooth(plt, ax, d, d[:smooth])
|
handleSmooth(plt, ax, d, d[:smooth])
|
||||||
|
|
||||||
# add the colorbar legend
|
# add the colorbar legend
|
||||||
if needs_colorbar && attr(d[:subplot], :colorbar) != :none
|
sp = d[:subplot]
|
||||||
|
if needs_colorbar && sp.attr[:colorbar] != :none
|
||||||
# cbar = PyPlot.colorbar(handles[end], ax=ax)
|
# cbar = PyPlot.colorbar(handles[end], ax=ax)
|
||||||
|
|
||||||
# do we need a discrete colorbar?
|
# do we need a discrete colorbar?
|
||||||
if discrete_colorbar_values == nothing
|
handle = handles[end]
|
||||||
PyPlot.colorbar(handles[end], ax=ax)
|
kw = KW()
|
||||||
else
|
if discrete_colorbar_values != nothing
|
||||||
# add_pyfixedformatter(cbar, discrete_colorbar_values)
|
|
||||||
locator, formatter = get_locator_and_formatter(discrete_colorbar_values)
|
locator, formatter = get_locator_and_formatter(discrete_colorbar_values)
|
||||||
vals = 1:length(discrete_colorbar_values)
|
kw[:values] = 1:length(discrete_colorbar_values)
|
||||||
PyPlot.colorbar(handles[end],
|
kw[:ticks] = locator
|
||||||
ax = ax,
|
kw[:format] = formatter
|
||||||
ticks = locator,
|
kw[:boundaries] = vcat(0, kw[:values] + 0.5)
|
||||||
format = formatter,
|
|
||||||
boundaries = vcat(0, vals + 0.5),
|
|
||||||
values = vals
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fig = plt.o
|
||||||
|
cbax = fig[:add_axes]([0.8,0.1,0.03,0.8])
|
||||||
|
sp.attr[:cbar_handle] = fig[:colorbar](handle, cax = cbax, kw...)
|
||||||
|
sp.attr[:cbar_ax] = cbax
|
||||||
|
|
||||||
|
# if discrete_colorbar_values == nothing
|
||||||
|
# PyPlot.colorbar(handles[end], ax=ax)
|
||||||
|
# else
|
||||||
|
# # add_pyfixedformatter(cbar, discrete_colorbar_values)
|
||||||
|
# locator, formatter = get_locator_and_formatter(discrete_colorbar_values)
|
||||||
|
# vals = 1:length(discrete_colorbar_values)
|
||||||
|
# PyPlot.colorbar(handles[end],
|
||||||
|
# ax = ax,
|
||||||
|
# ticks = locator,
|
||||||
|
# format = formatter,
|
||||||
|
# boundaries = vcat(0, vals + 0.5),
|
||||||
|
# values = vals
|
||||||
|
# )
|
||||||
|
# end
|
||||||
end
|
end
|
||||||
|
|
||||||
# this sets the bg color inside the grid
|
# this sets the bg color inside the grid
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user