Add legend angle to pyplot

This commit is contained in:
David Gustavsson 2021-03-02 10:19:26 +01:00
parent 37252ec562
commit d6a72a5df5
2 changed files with 57 additions and 41 deletions

View File

@ -1305,44 +1305,26 @@ end
# ----------------------------------------------------------------- # -----------------------------------------------------------------
py_legend_pos(pos::Symbol) = get( py_legend_pos(pos::Tuple{S,T}) where {S<:Real,T<:Real} = "lower left"
(
right = "right", function py_legend_pos(pos::Tuple{<:Real,Symbol})
left = "center left", (s,c) = sincosd(pos[1])
top = "upper center", if pos[2] === :outer
bottom = "lower center", s = -s
bottomleft = "lower left", c = -c
bottomright = "lower right", end
topright = "upper right", yanchors = ["lower","center","upper"]
topleft = "upper left", xanchors = ["left","center","right"]
outerright = "center left", return join([yanchors[legend_anchor_index(s)], xanchors[legend_anchor_index(c)]], ' ')
outerleft = "right", end
outertop = "lower center",
outerbottom = "upper center", function py_legend_bbox(pos::Tuple{T,Symbol}) where T<:Real
outerbottomleft = "lower right", if pos[2] === :outer
outerbottomright = "lower left", return legend_pos_from_angle(pos[1],-0.15,0.5,1.0,-0.15,0.5,1.0)
outertopright = "upper left", end
outertopleft = "upper right", legend_pos_from_angle(pos[1],0.0,0.5,1.0,0.0,0.5,1.0)
), end
pos,
"best",
)
py_legend_pos(pos) = "lower left"
py_legend_bbox(pos::Symbol) = get(
(
outerright = (1.0, 0.5, 0.0, 0.0),
outerleft = (-0.15, 0.5, 0.0, 0.0),
outertop = (0.5, 1.0, 0.0, 0.0),
outerbottom = (0.5, -0.15, 0.0, 0.0),
outerbottomleft = (-0.15, 0.0, 0.0, 0.0),
outerbottomright = (1.0, 0.0, 0.0, 0.0),
outertopright = (1.0, 1.0, 0.0, 0.0),
outertopleft = (-0.15, 1.0, 0.0, 0.0),
),
pos,
(0.0, 0.0, 1.0, 1.0),
)
py_legend_bbox(pos) = pos py_legend_bbox(pos) = pos
function py_add_legend(plt::Plot, sp::Subplot, ax) function py_add_legend(plt::Plot, sp::Subplot, ax)
@ -1388,6 +1370,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
# if anything was added, call ax.legend and set the colors # if anything was added, call ax.legend and set the colors
if !isempty(handles) if !isempty(handles)
leg = legend_angle(leg)
leg = ax."legend"(handles, leg = ax."legend"(handles,
labels, labels,
loc = py_legend_pos(leg), loc = py_legend_pos(leg),
@ -1398,7 +1381,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax)
edgecolor = py_color(sp[:foreground_color_legend]), edgecolor = py_color(sp[:foreground_color_legend]),
framealpha = alpha(plot_color(sp[:background_color_legend])), framealpha = alpha(plot_color(sp[:background_color_legend])),
fancybox = false, # makes the legend box square fancybox = false, # makes the legend box square
borderpad=0.8 # to match GR legendbox borderpad = 0.8 # to match GR legendbox
) )
frame = leg."get_frame"() frame = leg."get_frame"()
frame."set_linewidth"(py_thickness_scale(plt, 1)) frame."set_linewidth"(py_thickness_scale(plt, 1))

View File

@ -17,10 +17,43 @@ end
""" """
Split continuous range `[-1,1]` into an integer `[1,2,3]` Split continuous range `[-1,1]` evenly into an integer `[1,2,3]`
""" """
function legend_anchor_index(x) function legend_anchor_index(x)
x<-1//3 && return 1 x<-1//3 && return 1
x<1//3 && return 2 x<1//3 && return 2
return 3 return 3
end end
"""
Turn legend argument into a (theta, :inner) or (theta, :outer) tuple.
For backends where legend position is given in normal coordinates (0,0) -- (1,1),
so :topleft exactly corresponds to (45, :inner) etc.
If `leg` is a (::Real,::Real) tuple, keep it as is.
"""
legend_angle(leg::Real) = (leg,:inner)
legend_angle(leg::Tuple{S,T}) where {S<:Real,T<:Real} = leg
legend_angle(leg::Tuple{S,Symbol}) where S<:Real = leg
legend_angle(leg::Symbol) = get(
(
topleft = (135,:inner),
top = (90, :inner),
topright = (45, :inner),
left = (180,:inner),
right = (0, :inner),
bottomleft = (225,:inner),
bottom = (270,:inner),
bottomright = (315,:inner),
outertopleft = (135,:outer),
outertop = (90, :outer),
outertopright = (45, :outer),
outerleft = (180,:outer),
outerright = (0, :outer),
outerbottomleft = (225,:outer),
outerbottom = (270,:outer),
outerbottomright = (315,:outer),
),
leg,
(45, :inner)
)