15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 | class CollisionManager:
"""
Container for methods related to calculating difference values
for object collision avoidance.
"""
def __init__(
self,
figure_manager: FigureManager,
constants: Constants,
) -> None:
self.figure_manager = figure_manager
self.constants = constants
def _get_diff_img_plateau(
self,
margins: dict[str, tuple],
figsize: tuple[float, float],
) -> float:
"""Compute vertical spacing value for image plateau distance in data coordinates."""
diff_to_plateau = (
(margins["y"][1] - margins["y"][0])
/ figsize[1]
* self.constants.DISTANCE_IMAGE_LINE
)
return diff_to_plateau
def _get_diff_img_number(
self,
margins: dict[str, tuple],
figsize: tuple[float, float],
fontsize: int,
) -> float:
"""Compute vertical spacing value for image number distance in data coordinates."""
diff_to_number = (
(fontsize / self.constants.STD_FONTSIZE)
* (margins["y"][1] - margins["y"][0])
/ figsize[1]
* self.constants.DISTANCE_NUMBER_LINE
)
return diff_to_number
def _get_diff_to_label(
self,
margins: dict[str, tuple],
figsize: tuple[float, float],
) -> float:
"""Compute vertical spacing needed for label placement in data coordinates."""
diff_to_label = (
(margins["y"][1] - margins["y"][0])
/ figsize[1]
* (self.constants.DISTANCE_TO_LABEL)
)
return diff_to_label
def _get_label_boundaries(
self,
label: Text,
) -> tuple[float, float]:
"""
Get vertical maximum and minimum y boundaries of a label in data coordinates.
Returns
-------
tuple
A tuple of (y_min, y_max) for the label in data coordinates.
"""
label_window = label.get_window_extent().transformed(
self.figure_manager.ax.transData.inverted()
)
y_min = label_window.ymin
y_max = label_window.ymax
return (y_min, y_max)
def _get_number_diffs(
self,
margins: dict[str, tuple],
figsize: tuple[float, float],
fontsize: int,
) -> tuple[float, float]:
"""
Compute vertical spacing values for label placement in data coordinates.
Both values scale proportionally with font size, y-axis range, and
figure height so that spacing remains visually consistent regardless
of the diagram's scale.
Returns
-------
diff_bias : float
The vertical gap between an energy bar and the first label.
diff_per_step : float
The vertical distance between consecutive stacked labels.
"""
diff_bias = (
(fontsize / self.constants.STD_FONTSIZE)
* (margins["y"][1] - margins["y"][0])
/ figsize[1]
* self.constants.DISTANCE_NUMBER_LINE
)
diff_per_step = (
(fontsize / self.constants.STD_FONTSIZE)
* (margins["y"][1] - margins["y"][0])
/ figsize[1]
* self.constants.DISTANCE_NUMBER_NUMBER
)
return diff_bias, diff_per_step
def _get_axis_break_stopper_differences(
self,
margins: dict[str, tuple],
figsize: tuple[float, float],
angle: float,
) -> tuple[float, float]:
"""
Compute data coordinate differences for axis break stoppers in x and y directions.
"""
delta_x = (
np.cos(angle * np.pi / 180)
* 0.001
* (margins["x"][1] - margins["x"][0])
/ figsize[0]
)
delta_y = (
np.sin(angle * np.pi / 180)
* 0.001
* (margins["y"][1] - margins["y"][0])
/ figsize[1]
)
return delta_x, delta_y
def _get_axis_break_whitespace_cover_width(
self,
margins: dict[str, tuple],
figsize: tuple[float, float],
) -> float:
"""Compute data coordinate width for axis break whitespace cover."""
cover_width = (
self.constants.MERGED_PLATEAU_COVER_WIDTH
* (margins["y"][1] - margins["y"][0])
/ figsize[1]
)
return cover_width
|