Determine the best location to place the legend.
(self, width, height, renderer)
| 1178 | pad, pad) |
| 1179 | |
| 1180 | def _find_best_position(self, width, height, renderer): |
| 1181 | """Determine the best location to place the legend.""" |
| 1182 | assert self.isaxes # always holds, as this is only called internally |
| 1183 | |
| 1184 | start_time = time.perf_counter() |
| 1185 | |
| 1186 | bboxes, lines, offsets = self._auto_legend_data(renderer) |
| 1187 | |
| 1188 | bbox = Bbox.from_bounds(0, 0, width, height) |
| 1189 | |
| 1190 | candidates = [] |
| 1191 | for idx in range(1, len(self.codes)): |
| 1192 | l, b = self._get_anchored_bbox(idx, bbox, |
| 1193 | self.get_bbox_to_anchor(), |
| 1194 | renderer) |
| 1195 | legendBox = Bbox.from_bounds(l, b, width, height) |
| 1196 | # XXX TODO: If markers are present, it would be good to take them |
| 1197 | # into account when checking vertex overlaps in the next line. |
| 1198 | badness = (sum(legendBox.count_contains(line.vertices) |
| 1199 | for line in lines) |
| 1200 | + legendBox.count_contains(offsets) |
| 1201 | + legendBox.count_overlaps(bboxes) |
| 1202 | + sum(line.intersects_bbox(legendBox, filled=False) |
| 1203 | for line in lines)) |
| 1204 | # Include the index to favor lower codes in case of a tie. |
| 1205 | candidates.append((badness, idx, (l, b))) |
| 1206 | if badness == 0: |
| 1207 | break |
| 1208 | |
| 1209 | _, _, (l, b) = min(candidates) |
| 1210 | |
| 1211 | if self._loc_used_default and time.perf_counter() - start_time > 1: |
| 1212 | _api.warn_external( |
| 1213 | 'Creating legend with loc="best" can be slow with large ' |
| 1214 | 'amounts of data.') |
| 1215 | |
| 1216 | return l, b |
| 1217 | |
| 1218 | def contains(self, mouseevent): |
| 1219 | return self.legendPatch.contains(mouseevent) |
no test coverage detected