diff --git a/tests/test_canvas.py b/tests/test_canvas.py index 071ca78..ff46d5e 100644 --- a/tests/test_canvas.py +++ b/tests/test_canvas.py @@ -56,6 +56,14 @@ def test_namespaces(backend: str): canvas.y.label.family = "Arial" assert canvas.y.label.family == "Arial" + # test lim + canvas.x.lim = (-1, 1) + assert canvas.x.lim == pytest.approx((-1, 1)) + canvas.x.lim = (-0.4, None) + assert canvas.x.lim == pytest.approx((-0.4, 1)) + canvas.x.lim = (None, 0.6) + assert canvas.x.lim == pytest.approx((-0.4, 0.6)) + # test errors with pytest.raises(ValueError): canvas.x.lim = (1, 0) diff --git a/whitecanvas/backend/matplotlib/_labels.py b/whitecanvas/backend/matplotlib/_labels.py index 04d1bb5..080651b 100644 --- a/whitecanvas/backend/matplotlib/_labels.py +++ b/whitecanvas/backend/matplotlib/_labels.py @@ -202,9 +202,9 @@ def _plt_get_limits(self) -> tuple[float, float]: axes = self._canvas()._axes x0, x1 = getattr(axes, f"get_{self._axis_name}lim")() if getattr(axes, f"{self._axis_name}axis_inverted")(): - return x1, x0 + return float(x1), float(x0) else: - return x0, x1 + return float(x0), float(x1) def _plt_set_limits(self, limits: tuple[float, float]): axes = self._canvas()._axes diff --git a/whitecanvas/canvas/_namespaces.py b/whitecanvas/canvas/_namespaces.py index 9a03d09..431b686 100644 --- a/whitecanvas/canvas/_namespaces.py +++ b/whitecanvas/canvas/_namespaces.py @@ -312,7 +312,11 @@ def lim(self) -> tuple[float, float]: @lim.setter def lim(self, lim: tuple[float, float]): low, high = lim - if low >= high: + if low is None or high is None: + _low, _high = self._get_object()._plt_get_limits() + low = low if low is not None else _low + high = high if high is not None else _high + elif low >= high: a = type(self).__name__[0].lower() raise ValueError( f"low must be less than high, but got {lim!r}. If you " @@ -322,8 +326,9 @@ def lim(self, lim: tuple[float, float]): # implemented in JS (such as bokeh) and the python callback is not # enabled. Otherwise axis linking fails. with self.events.blocked(): - self._get_object()._plt_set_limits(lim) - self.events.lim.emit(lim) + self._get_object()._plt_set_limits((low, high)) + self.events.lim.emit((low, high)) + self._draw_canvas() return None @property