Skip to content

Commit

Permalink
Use rel_position to calculate alignment positions in the layout
Browse files Browse the repository at this point in the history
  • Loading branch information
has2k1 committed Jan 2, 2025
1 parent 5205636 commit c93ee89
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 22 deletions.
55 changes: 33 additions & 22 deletions plotnine/_mpl/layout_manager/_layout_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from ..utils import (
bbox_in_figure_space,
get_transPanels,
rel_position,
tight_bbox_in_figure_space,
)

Expand Down Expand Up @@ -534,9 +535,9 @@ def horizontally_align_text(
"center": 0.5,
"right": 1.0,
}
f = lookup[ha]
rel = lookup[ha]
else:
f = ha
rel = ha

if how == "panel":
left = spaces.l.left
Expand All @@ -546,7 +547,7 @@ def horizontally_align_text(
right = spaces.r.plot_right

width = spaces.items.calc.width(text)
x = left * (1 - f) + (right - width) * f
x = rel_position(rel, width, left, right)
text.set_x(x)
text.set_horizontalalignment("left")

Expand All @@ -571,9 +572,9 @@ def vertically_align_text(
"center_baseline": 0.5,
"bottom": 0.0,
}
f = lookup[va]
rel = lookup[va]
else:
f = va
rel = va

if how == "panel":
top = spaces.t.top
Expand All @@ -583,7 +584,7 @@ def vertically_align_text(
bottom = spaces.b.plot_bottom

height = spaces.items.calc.height(text)
y = bottom * (1 - f) + (top - height) * f
y = rel_position(rel, height, bottom, top)
text.set_y(y)
text.set_verticalalignment("bottom")

Expand Down Expand Up @@ -619,32 +620,42 @@ def set_position(
aob.set_bbox_to_anchor(anchor_point, transform) # type: ignore

if legends.right:
j = legends.right.justification
y = (
params.bottom * (1 - j)
+ (params.top - spaces.r._legend_height) * j
y = rel_position(
legends.right.justification,
spaces.r._legend_height,
params.bottom,
params.top,
)
x = spaces.r.x2("legend")
set_position(legends.right.box, (x, y), (1, 0))

if legends.left:
j = legends.left.justification
y = (
params.bottom * (1 - j)
+ (params.top - spaces.l._legend_height) * j
y = rel_position(
legends.left.justification,
spaces.l._legend_height,
params.bottom,
params.top,
)
x = spaces.l.x1("legend")
set_position(legends.left.box, (x, y), (0, 0))

if legends.top:
j = legends.top.justification
x = params.left * (1 - j) + (params.right - spaces.t._legend_width) * j
x = rel_position(
legends.top.justification,
spaces.t._legend_width,
params.left,
params.right,
)
y = spaces.t.y2("legend")
set_position(legends.top.box, (x, y), (0, 1))

if legends.bottom:
j = legends.bottom.justification
x = params.left * (1 - j) + (params.right - spaces.b._legend_width) * j
x = rel_position(
legends.bottom.justification,
spaces.b._legend_width,
params.left,
params.right,
)
y = spaces.b.y1("legend")
set_position(legends.bottom.box, (x, y), (0, 0))

Expand Down Expand Up @@ -680,17 +691,17 @@ def set_plot_tag_position(tag: Text, spaces: LayoutSpaces):
}

if isinstance(position, str):
# Coordinates of the space to place the tag
# Coordinates of the space in which to place the tag
if location == "plot":
(x1, y1), (x2, y2) = spaces.plot_area_coordinates
else:
(x1, y1), (x2, y2) = spaces.panel_area_coordinates

# Calculate the position when the tag has no margins
fx, fy = lookup[position]
rel_x, rel_y = lookup[position]
width, height = spaces.items.calc.size(tag)
x = x1 * (1 - fx) + (x2 - width) * fx
y = y1 * (1 - fy) + (y2 - height) * fy
x = rel_position(rel_x, width, x1, x2)
y = rel_position(rel_y, height, y1, y2)

# Adjust the position to account for the margins
# When the units for the margin are in the figure coordinates,
Expand Down
18 changes: 18 additions & 0 deletions plotnine/_mpl/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,21 @@ def get_transPanels(fig: Figure) -> Transform:
dx, dy = params.left * W, params.bottom * H
transFiguretoPanels = Affine2D().scale(sx, sy).translate(dx, dy)
return fig.transFigure + transFiguretoPanels


def rel_position(rel: float, length: float, low: float, high: float) -> float:
"""
Relatively position an object of a given length between two position
Parameters
----------
rel:
Relative position of the object between the limits.
length:
Length of the object
low:
Lower limit position
high:
Upper limit position
"""
return low * (1 - rel) + (high - length) * rel

0 comments on commit c93ee89

Please sign in to comment.