Skip to content

Commit

Permalink
gr: fix legend (#4492)
Browse files Browse the repository at this point in the history
  • Loading branch information
t-bltg committed Nov 3, 2022
1 parent 6206ac0 commit 1220ab0
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 52 deletions.
36 changes: 17 additions & 19 deletions src/axes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
k_min = scale _logScales ? 2 : 4, # minimum number of ticks
k_max = 8, # maximum number of ticks
scale = scale,
)[1]
) |> first
elseif typeof(ticks) <: Int
optimize_ticks(
sf(amin),
Expand All @@ -172,13 +172,13 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
# chosen ticks is not too much bigger than amin - amax:
strict_span = false,
scale = scale,
)[1]
) |> first
else
map(sf, (filter(t -> amin t amax, ticks)))
map(sf, filter(t -> amin t amax, ticks))
end
unscaled_ticks = map(RecipesPipeline.inverse_scale_func(scale), scaled_ticks)

labels = if any(isfinite, unscaled_ticks)
labels::Vector{String} = if any(isfinite, unscaled_ticks)
if formatter in (:auto, :plain, :scientific, :engineering)
map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, formatter))
elseif formatter === :latex
Expand All @@ -193,9 +193,6 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
map(formatter, unscaled_ticks)
# if the formatter left us with numbers, still apply the default formatter
# However it leave us with the problem of unicode number decoding by the backend
# if eltype(unscaled_ticks) <: Number
# Showoff.showoff(unscaled_ticks, :auto)
# end
end
else
String[] # no finite ticks to show...
Expand All @@ -204,18 +201,18 @@ function optimal_ticks_and_labels(ticks, alims, scale, formatter)
unscaled_ticks, labels
end

# return (continuous_values, discrete_values) for the ticks on this axis
# returns (continuous_values, discrete_values) for the ticks on this axis
function get_ticks(sp::Subplot, axis::Axis; update = true, formatter = axis[:formatter])
if update || !haskey(axis.plotattributes, :optimized_ticks)
dvals = axis[:discrete_values]
ticks = _transform_ticks(axis[:ticks], axis)
axis.plotattributes[:optimized_ticks] =
if (
axis[:letter] === :x &&
ticks isa Symbol &&
ticks !== :none &&
ispolar(sp) &&
axis[:letter] === :x &&
!isempty(dvals)
!isempty(dvals) &&
ispolar(sp)
)
collect(0:/ 4):(7π / 4)), string.(0:45:315)
else
Expand Down Expand Up @@ -285,22 +282,22 @@ for l in (:x, :y, :z)
end
# get_ticks from axis symbol :x, :y, or :z
get_ticks(sp::Subplot, s::Symbol) = get_ticks(sp, sp[get_attr_symbol(s, :axis)])
get_ticks(p::Plot, s::Symbol) = [get_ticks(sp, s) for sp in p.subplots]
get_ticks(p::Plot, s::Symbol) = map(sp -> get_ticks(sp, s), p.subplots)

get_ticks(ticks::Symbol, cvals::T, dvals, args...) where {T} =
if ticks === :none
return T[], String[]
T[], String[]
elseif !isempty(dvals)
n = length(dvals)
if ticks === :all || n < 16
return cvals, string.(dvals)
cvals, string.(dvals)
else
Δ = ceil(Int, n / 10)
rng = Δ:Δ:n
return cvals[rng], string.(dvals[rng])
cvals[rng], string.(dvals[rng])
end
else
return optimal_ticks_and_labels(nothing, args...)
optimal_ticks_and_labels(nothing, args...)
end

get_ticks(ticks::AVec, cvals, dvals, args...) = optimal_ticks_and_labels(ticks, args...)
Expand All @@ -315,7 +312,8 @@ get_ticks(ticks::NTuple{2,Any}, args...) = ticks
get_ticks(::Nothing, cvals::T, args...) where {T} = T[], String[]
get_ticks(ticks::Bool, args...) =
ticks ? get_ticks(:auto, args...) : get_ticks(nothing, args...)
get_ticks(::T, args...) where {T} = error("Unknown ticks type in get_ticks: $T")
get_ticks(::T, args...) where {T} =
throw(ArgumentError("Unknown ticks type in get_ticks: $T"))

_transform_ticks(ticks, axis) = ticks
_transform_ticks(ticks::AbstractArray{T}, axis) where {T<:Dates.TimeType} =
Expand Down Expand Up @@ -836,7 +834,7 @@ function axis_drawing_info(sp, letter)
oax,
oas,
oamM,
ticks[1],
first(ticks),
ax[:grid],
tick_segments,
grid_segments,
Expand Down Expand Up @@ -983,7 +981,7 @@ function axis_drawing_info_3d(sp, letter)
nas,
fas,
namM,
ticks[1],
first(ticks),
ax[:grid],
tick_segments,
grid_segments,
Expand Down
27 changes: 13 additions & 14 deletions src/backends/gr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ function _update_min_padding!(sp::Subplot{GRBackend})
sp,
ax;
halign = (:left, :hcenter, :right)[sign(rot) + 2],
valign = (ax[:mirror] ? :bottom : :top),
valign = ax[:mirror] ? :bottom : :top,
)
l = 0.01 + last(gr_get_ticks_size(tc, rot))
m = max(m, 1mm + height * l * px)
Expand All @@ -834,7 +834,7 @@ function _update_min_padding!(sp::Subplot{GRBackend})
gr_set_tickfont(
sp,
zaxis;
halign = (zaxis[:mirror] ? :left : :right),
halign = zaxis[:mirror] ? :left : :right,
valign = (:top, :vcenter, :bottom)[sign(rot) + 2],
)
l = 0.01 + first(gr_get_ticks_size(zticks, rot))
Expand Down Expand Up @@ -1088,39 +1088,38 @@ function gr_legend_pos(sp::Subplot, leg, vp)
return gr_legend_pos(lp, vp)
end
if (leg_str = string(lp)) == "best"
# leg_str = ymirror ? "topleft" : "topright" # for twinx ?
leg_str = "topright"
end
xpos = if occursin("left", leg_str)
if occursin("outer", leg_str)
-!ymirror * gr_axis_width(sp, yaxis) - 2leg.xoffset - leg.rightw - leg.textw
vp.xmin + if occursin("outer", leg_str)
-!ymirror * gr_axis_width(sp, yaxis) - leg.rightw - leg.textw - 2leg.xoffset
else
leg.leftw + leg.xoffset
end + vp.xmin
end
elseif occursin("right", leg_str)
if occursin("outer", leg_str) # per https://github.com/jheinen/GR.jl/blob/master/src/jlgr.jl#L525
vp.xmax + if occursin("outer", leg_str) # per github.com/jheinen/GR.jl/blob/master/src/jlgr.jl#L525
leg.xoffset + leg.leftw + ymirror * gr_axis_width(sp, yaxis)
else
-leg.rightw - leg.textw - leg.xoffset
end + vp.xmax
end
else
vp.xmin + leg.leftw - leg.rightw - leg.textw - 2leg.xoffset
vp.xmin + 0.5width(vp) + leg.leftw - leg.rightw - leg.textw - 2leg.xoffset
end
ypos = if occursin("bottom", leg_str)
if lp === :outerbottom
vp.ymin + if lp === :outerbottom
-leg.yoffset - leg.dy - !xmirror * gr_axis_height(sp, xaxis)
else
leg.yoffset + leg.h
end + vp.ymin
end
elseif occursin("top", leg_str)
if lp === :outertop
vp.ymax + if lp === :outertop
leg.yoffset + leg.h + xmirror * gr_axis_height(sp, xaxis)
else
-leg.yoffset - leg.dy
end + vp.ymax
end
else
# Adding min y to shift legend pos to correct graph (#2377)
0.5(height(vp) + leg.h) + vp.ymin
vp.ymin + 0.5(height(vp) + leg.h)
end
xpos, ypos
end
Expand Down
12 changes: 6 additions & 6 deletions src/backends/inspectdr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,20 +113,20 @@ function _inspectdr_getaxisticks(ticks, gridlines, xfrm)
end

function _inspectdr_setticks(sp::Subplot, plot, strip, xaxis, yaxis)
InputXfrm1D = InspectDR.InputXfrm1D
_get_ticks(axis) = :native == axis[:ticks] ? (:native) : get_ticks(sp, axis)
wantnative(ticks) = (:native == ticks)
_get_ticks(axis) = axis[:ticks] === :native ? :native : get_ticks(sp, axis)

xticks = _get_ticks(xaxis)
yticks = _get_ticks(yaxis)

(wantnative(xticks) && wantnative(yticks)) && return # Don't "eval" tick values
(xticks === :native && yticks === :native) && return # Don't "eval" tick values

# TODO: Allow InspectDR to independently "eval" x or y ticks
ext = InspectDR.getextents_aloc(plot, 1)
grid = InspectDR._eval(strip.grid, plot.xscale, strip.yscale, ext)
grid.xlines = _inspectdr_getaxisticks(xticks, grid.xlines, InputXfrm1D(plot.xscale))
grid.ylines = _inspectdr_getaxisticks(yticks, grid.ylines, InputXfrm1D(strip.yscale))
grid.xlines =
_inspectdr_getaxisticks(xticks, grid.xlines, InspectDR.InputXfrm1D(plot.xscale))
grid.ylines =
_inspectdr_getaxisticks(yticks, grid.ylines, InspectDR.InputXfrm1D(strip.yscale))
strip.grid = grid
end

Expand Down
19 changes: 6 additions & 13 deletions src/layouts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ function recompute_lengths(v)
end

# now fill in the blanks
Measure[(vi == 0pct ? leftover / cnt : vi) for vi in v]
map(x -> x == 0pct ? leftover / cnt : x, v)
end

# recursively compute the bounding boxes for the layout and plotarea (relative to canvas!)
Expand Down Expand Up @@ -352,8 +352,8 @@ function update_child_bboxes!(
child = layout[r, c]

# get the top-left corner of this child... the first one is top-left of the parent (i.e. layout)
child_left = (c == 1 ? left(layout.bbox) : right(layout[r, c - 1].bbox))
child_top = (r == 1 ? top(layout.bbox) : bottom(layout[r - 1, c].bbox))
child_left = c == 1 ? left(layout.bbox) : right(layout[r, c - 1].bbox)
child_top = r == 1 ? top(layout.bbox) : bottom(layout[r - 1, c].bbox)

# compute plot area
plotarea_left = child_left + pad_left[c]
Expand Down Expand Up @@ -385,7 +385,7 @@ end

# for each inset (floating) subplot, resolve the relative position
# to absolute canvas coordinates, relative to the parent's plotarea
function update_inset_bboxes!(plt::Plot)
update_inset_bboxes!(plt::Plot) =
for sp in plt.inset_subplots
p_area = Measures.resolve(plotarea(sp.parent), sp[:relative_bbox])
plotarea!(sp, p_area)
Expand All @@ -400,18 +400,11 @@ function update_inset_bboxes!(plt::Plot)
),
)
end
end

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

calc_num_subplots(layout::AbstractLayout) = get(layout.attr, :blank, false) ? 0 : 1
function calc_num_subplots(layout::GridLayout)
tot = 0
for l in layout.grid
tot += calc_num_subplots(l)
end
tot
end
calc_num_subplots(layout::GridLayout) = sum(map(l -> calc_num_subplots(l), layout.grid))

function compute_gridsize(numplts::Int, nr::Int, nc::Int)
# figure out how many rows/columns we need
Expand Down Expand Up @@ -479,7 +472,7 @@ layout_args(nt::NamedTuple) = EmptyLayout(; nt...), 1

function layout_args(m::AbstractVecOrMat)
sz = size(m)
nr = sz[1]
nr = first(sz)
nc = get(sz, 2, 1)
gl = GridLayout(nr, nc)
for ci in CartesianIndices(m)
Expand Down

0 comments on commit 1220ab0

Please sign in to comment.