From 789e4343a7df4a1556417cbc65abce79e0f7dd6c Mon Sep 17 00:00:00 2001 From: Stan West <38358698+stanwest@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:45:59 -0400 Subject: [PATCH 1/3] Add tests of irregular date-time image coordinates The expected failure is because of erroneous warning for regular coordinates with coarse granularity within the spacing. --- holoviews/tests/element/test_image.py | 52 +++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/holoviews/tests/element/test_image.py b/holoviews/tests/element/test_image.py index 74aaca1463..b157a85d9c 100644 --- a/holoviews/tests/element/test_image.py +++ b/holoviews/tests/element/test_image.py @@ -4,6 +4,8 @@ from __future__ import annotations +import datetime as dt + import numpy as np import pytest @@ -74,6 +76,56 @@ def test_image_rtol_config(self): hv.Image({"vals": vals, "xs": xs, "ys": ys}, ["xs", "ys"], "vals") hv.config.image_rtol = image_rtol + @pytest.mark.parametrize( + "x", + [ + # max(|step|) / min(|step|) - 1 = 0.0015 + [dt.datetime(2017, 1, 1, 0, 0, 0, ms) for ms in [0, 10000, 20015]], + *( + np.array([0, 10000, 20015]).astype(f"datetime64[{unit}]") + for unit in ["D", "h", "m", "s", "ms", "us"] + ), + ], + ) + def test_image_datetime_rtol_failure(self, x): + """ + Constructing an Image with a date-time coordinate warns about irregular sampling + if, approximately speaking, one less than the ratio of the max and min steps + exceeds the default `image_rtol`. + """ + y = np.arange(2) + hv.Image((x, y, np.zeros((len(y), len(x))))) + self.log_handler.assert_endswith( + "WARNING", + "set a higher tolerance on hv.config.image_rtol or the rtol parameter in " + "the Image constructor.", + ) + + @pytest.mark.xfail + @pytest.mark.parametrize( + "x", + [ + # |granularity / step| = 1/400 = 0.0025 + [dt.datetime(2017, 1, 1, 0, 0, 0, ms) for ms in [0, 400]], + # |granularity / step| = 1/800 = 0.00125 + *( + np.array([10000, 10800]).astype(f"datetime64[{unit}]") + for unit in ["D", "h", "m", "s", "ms", "us"] + ), + ], + ) + def test_image_datetime_rtol_granularity(self, x): + """ + Constructing an Image with an evenly spaced date-time coordinate does not warn + about irregular sampling, even when the ratio of the date-time granularity to + the coordinate step is greater than the default `image_rtol` (or twice + `image_rtol` for `datetime.datetime` types because of how they round when + multiplied by a `float`). + """ + y = np.arange(2) + hv.Image((x, y, np.zeros((len(y), len(x))))) + assert len(self.log_handler.tail("WARNING", n=1)) == 0 + def test_image_clone(self): vals = np.random.rand(20, 20) xs = np.linspace(0, 10, 20) From 1321e242ef59189adc4d23a9544d1502e31f1999 Mon Sep 17 00:00:00 2001 From: Stan West <38358698+stanwest@users.noreply.github.com> Date: Fri, 12 Jun 2026 10:37:51 -0400 Subject: [PATCH 2/3] Allow irregular sampling equal to the tolerance The change prevents an erroneous warning for regular date-time coordinates whose minimum step has coarse granularity in the internal date-time representation. For such a step, the right-hand side can evaluate to a time delta of zero (depending on how the object rounds when multiplied), and the former `<` inequality cannot be satisfied. Also, the change conforms the function to its docstring ("at most") and to the documentation of `Config.image_rtol` ("maximal allowable sampling difference"). --- holoviews/core/util/__init__.py | 2 +- holoviews/tests/element/test_image.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/holoviews/core/util/__init__.py b/holoviews/core/util/__init__.py index 906548f80a..ca9779a73f 100644 --- a/holoviews/core/util/__init__.py +++ b/holoviews/core/util/__init__.py @@ -2255,7 +2255,7 @@ def validate_regular_sampling(values, rtol=10e-6): if len(diffs) < 1: return True min_diff = diffs.min() - return abs(min_diff - diffs.max()) < abs(min_diff * rtol) + return abs(min_diff - diffs.max()) <= abs(min_diff * rtol) def compute_density(start, end, length, time_unit="us"): diff --git a/holoviews/tests/element/test_image.py b/holoviews/tests/element/test_image.py index b157a85d9c..e8032f3229 100644 --- a/holoviews/tests/element/test_image.py +++ b/holoviews/tests/element/test_image.py @@ -101,7 +101,6 @@ def test_image_datetime_rtol_failure(self, x): "the Image constructor.", ) - @pytest.mark.xfail @pytest.mark.parametrize( "x", [ From ade0ed34d6bd61704994cdd71de2f57001629ddd Mon Sep 17 00:00:00 2001 From: Stan West <38358698+stanwest@users.noreply.github.com> Date: Mon, 15 Jun 2026 12:55:02 -0400 Subject: [PATCH 3/3] Clarify description of test --- holoviews/tests/element/test_image.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/holoviews/tests/element/test_image.py b/holoviews/tests/element/test_image.py index e8032f3229..506660fb25 100644 --- a/holoviews/tests/element/test_image.py +++ b/holoviews/tests/element/test_image.py @@ -118,8 +118,8 @@ def test_image_datetime_rtol_granularity(self, x): Constructing an Image with an evenly spaced date-time coordinate does not warn about irregular sampling, even when the ratio of the date-time granularity to the coordinate step is greater than the default `image_rtol` (or twice - `image_rtol` for `datetime.datetime` types because of how they round when - multiplied by a `float`). + `image_rtol` for `dt.datetime` types because of how `dt.timedelta` instances + round when multiplied by a `float`). """ y = np.arange(2) hv.Image((x, y, np.zeros((len(y), len(x)))))