Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion holoviews/core/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"):
Expand Down
51 changes: 51 additions & 0 deletions holoviews/tests/element/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from __future__ import annotations

import datetime as dt

import numpy as np
import pytest

Expand Down Expand Up @@ -74,6 +76,55 @@ 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`.
"""
Comment on lines +91 to +95

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""
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`.
"""

Docstrings is not needed for tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand. I see the docstring as a natural place to explain the intent of a non-obvious test. Here, in particular, it relates the test to image_rtol, a relationship that isn't apparent from the test's parameters, which are declared independently of image_rtol. Would a comment be preferred over a docstring?

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.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
Comment on lines +107 to +109

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you choose two different ratios?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because datetime.timedelta and np.timedelta64 instances round differently when multiplied by a float such as image_rtol, the range of coordinate steps that will cause the false warning differs for the two types. (A datetime.timedelta instance rounds to the nearest microseconds, whereas a np.timedelta64 truncates toward zero.) Specifically, with image_rtol = 0.001, the false warning occurs for datetime.datetime steps of less than 500 microseconds and for np.datetime64 steps of less than 1000 units. For each type, I chose a step that is a little smaller than the largest sufficient step for that type.

*(
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`).
"""
Comment on lines +117 to +123

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""
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)
Expand Down
Loading