(self, layout, labels, label_props)
| 1070 | self._observers = cbook.CallbackRegistry(signals=["clicked"]) |
| 1071 | |
| 1072 | def _init_layout(self, layout, labels, label_props): |
| 1073 | |
| 1074 | label_props = _expand_text_props(label_props) |
| 1075 | |
| 1076 | if layout is None: |
| 1077 | # legacy hard-coded vertical layout |
| 1078 | self._buttons_xs = [0.15] * len(labels) |
| 1079 | self._buttons_ys = np.linspace(1, 0, len(labels)+2)[1:-1] |
| 1080 | self.labels = [ |
| 1081 | self.ax.text(0.25, y, label, transform=self.ax.transAxes, |
| 1082 | horizontalalignment="left", verticalalignment="center", |
| 1083 | **props) |
| 1084 | for y, label, props in zip(self._buttons_ys, labels, label_props)] |
| 1085 | return |
| 1086 | |
| 1087 | # New layout algorithm with text measurement |
| 1088 | # Parse layout parameter |
| 1089 | n_labels = len(labels) |
| 1090 | match layout: |
| 1091 | case "vertical": |
| 1092 | n_rows, n_cols = n_labels, 1 |
| 1093 | case "horizontal": |
| 1094 | n_rows, n_cols = 1, n_labels |
| 1095 | case (int() as n_rows, int() as n_cols): |
| 1096 | if n_rows * n_cols < n_labels: |
| 1097 | raise ValueError( |
| 1098 | f"layout {layout} has {n_rows * n_cols} positions but " |
| 1099 | f"{n_labels} labels were provided" |
| 1100 | ) |
| 1101 | case _: |
| 1102 | raise ValueError( |
| 1103 | "layout must be None, 'vertical', 'horizontal', or a (rows, cols) " |
| 1104 | f"tuple; got {layout!r}") |
| 1105 | |
| 1106 | # Define spacing in points for DPI-independent sizing |
| 1107 | fig = self.ax.get_figure(root=False) |
| 1108 | axes_width_display = 72 * self.ax.bbox.transformed( |
| 1109 | fig.dpi_scale_trans.inverted() |
| 1110 | ).width |
| 1111 | left_margin_display = 11 # points |
| 1112 | button_text_offset_display = 5.5 # points |
| 1113 | col_spacing_display = 11 # points |
| 1114 | |
| 1115 | # Convert to axes coordinates |
| 1116 | left_margin = left_margin_display / axes_width_display |
| 1117 | button_text_offset = button_text_offset_display / axes_width_display |
| 1118 | col_spacing = col_spacing_display / axes_width_display |
| 1119 | |
| 1120 | # Create text objects to measure widths. |
| 1121 | # We create Text objects directly rather than using ax.text() since we're |
| 1122 | # only measuring them and only later add them to the axes. |
| 1123 | self.labels = [ |
| 1124 | mtext.Text(0, 0, text=label, transform=self.ax.transAxes, |
| 1125 | horizontalalignment="left", verticalalignment="center", |
| 1126 | **props) |
| 1127 | for label, props in zip(labels, label_props) |
| 1128 | ] |
| 1129 | # Set figure reference so Text objects can access figure properties |
no test coverage detected