|
15 | 15 | _to_unmasked_float_array, ls_mapper, ls_mapper_r, STEP_LOOKUP_MAP)
|
16 | 16 | from .markers import MarkerStyle
|
17 | 17 | from .path import Path
|
18 |
| -from .transforms import Bbox, TransformedPath |
| 18 | +from .transforms import ( |
| 19 | + Affine2D, Bbox, BboxTransformFrom, BboxTransformTo, TransformedPath) |
19 | 20 |
|
20 | 21 | # Imported here for backward compatibility, even though they don't
|
21 | 22 | # really belong.
|
@@ -1448,6 +1449,42 @@ def is_dashed(self):
|
1448 | 1449 | return self._linestyle in ('--', '-.', ':')
|
1449 | 1450 |
|
1450 | 1451 |
|
| 1452 | +class _AxLine(Line2D): |
| 1453 | + def get_transform(self): |
| 1454 | + ax = self.axes |
| 1455 | + (x1, y1), (x2, y2) = ax.transScale.transform([*zip(*self.get_data())]) |
| 1456 | + dx = x2 - x1 |
| 1457 | + dy = y2 - y1 |
| 1458 | + if np.allclose(x1, x2): |
| 1459 | + if np.allclose(y1, y2): |
| 1460 | + raise ValueError( |
| 1461 | + f"Cannot draw a line through two identical points " |
| 1462 | + f"(x={self.get_xdata()}, y={self.get_ydata()})") |
| 1463 | + # First send y1 to 0 and y2 to 1. |
| 1464 | + return (Affine2D.from_values(1, 0, 0, 1 / dy, 0, -y1 / dy) |
| 1465 | + + ax.get_xaxis_transform(which="grid")) |
| 1466 | + if np.allclose(y1, y2): |
| 1467 | + # First send x1 to 0 and x2 to 1. |
| 1468 | + return (Affine2D.from_values(1 / dx, 0, 0, 1, -x1 / dx, 0) |
| 1469 | + + ax.get_yaxis_transform(which="grid")) |
| 1470 | + (vxlo, vylo), (vxhi, vyhi) = ax.transScale.transform(ax.viewLim) |
| 1471 | + # General case: find intersections with view limits in either |
| 1472 | + # direction, and draw between the middle two points. |
| 1473 | + _, start, stop, _ = sorted([ |
| 1474 | + (vxlo, y1 + (vxlo - x1) * dy / dx), |
| 1475 | + (vxhi, y1 + (vxhi - x1) * dy / dx), |
| 1476 | + (x1 + (vylo - y1) * dx / dy, vylo), |
| 1477 | + (x1 + (vyhi - y1) * dx / dy, vyhi), |
| 1478 | + ]) |
| 1479 | + return (BboxTransformFrom(Bbox([*zip(*self.get_data())])) |
| 1480 | + + BboxTransformTo(Bbox([start, stop])) |
| 1481 | + + ax.transLimits + ax.transAxes) |
| 1482 | + |
| 1483 | + def draw(self, renderer): |
| 1484 | + self._transformed_path = None # Force regen. |
| 1485 | + super().draw(renderer) |
| 1486 | + |
| 1487 | + |
1451 | 1488 | class VertexSelector:
|
1452 | 1489 | """
|
1453 | 1490 | Manage the callbacks to maintain a list of selected vertices for
|
|
0 commit comments