Skip to content

Commit 9cabb73

Browse files
committed
Expand plot_xY integration tests for coverage
Add tests for histogram validation, single time point, object-dtype datetime x, ribbon ETI with fill_kwargs, and custom colormap; omit mock-based ETI edge case. Made-with: Cursor
1 parent 7fde974 commit 9cabb73

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

causalpy/tests/test_plot_utils.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,3 +447,88 @@ def test_plot_xY_histogram_custom_colormap(synthetic_posterior_data):
447447
assert patch is None, "Histogram should not return PolyCollection"
448448

449449
plt.close(fig)
450+
451+
452+
@pytest.mark.integration
453+
def test_plot_xY_histogram_requires_single_time_dim():
454+
"""Histogram rejects Y with more than one non-chain/draw dimension."""
455+
rng = np.random.default_rng(0)
456+
Y = xr.DataArray(
457+
rng.standard_normal((2, 30, 4, 5)),
458+
dims=["chain", "draw", "a", "b"],
459+
coords={
460+
"chain": [0, 1],
461+
"draw": np.arange(30),
462+
"a": np.arange(4),
463+
"b": np.arange(5),
464+
},
465+
)
466+
fig, ax = plt.subplots()
467+
with pytest.raises(ValueError, match="exactly one non-chain/draw"):
468+
plot_xY(np.arange(4), Y, ax=ax, kind="histogram")
469+
plt.close(fig)
470+
471+
472+
@pytest.mark.integration
473+
def test_plot_xY_histogram_x_length_mismatch_raises(synthetic_posterior_data):
474+
"""Histogram rejects x length differing from the posterior time dimension."""
475+
x, Y = synthetic_posterior_data
476+
fig, ax = plt.subplots()
477+
with pytest.raises(ValueError, match="Length of x"):
478+
plot_xY(x[:3], Y, ax=ax, kind="histogram")
479+
plt.close(fig)
480+
481+
482+
@pytest.mark.integration
483+
def test_plot_xY_histogram_single_time_point():
484+
"""Histogram with one time point exercises single-edge x bin construction."""
485+
rng = np.random.default_rng(2)
486+
x = pd.date_range("2020-01-01", periods=1, freq="D")
487+
Y = xr.DataArray(
488+
rng.standard_normal((2, 40, 1)),
489+
dims=["chain", "draw", "obs_ind"],
490+
coords={
491+
"chain": [0, 1],
492+
"draw": np.arange(40),
493+
"obs_ind": x,
494+
},
495+
)
496+
fig, ax = plt.subplots()
497+
handles, patch = plot_xY(x, Y, ax=ax, kind="histogram")
498+
assert isinstance(handles, list)
499+
assert patch is None
500+
plt.close(fig)
501+
502+
503+
@pytest.mark.integration
504+
def test_plot_xY_histogram_object_dtype_datetime_strings(synthetic_posterior_data):
505+
"""Object-dtype x of ISO strings hits datetime parsing in _x_as_numeric_mesh."""
506+
x, Y = synthetic_posterior_data
507+
x_obj = np.array([str(t) for t in x], dtype=object)
508+
fig, ax = plt.subplots()
509+
handles, patch = plot_xY(x_obj, Y, ax=ax, kind="histogram")
510+
assert isinstance(handles, list)
511+
assert patch is None
512+
plt.close(fig)
513+
514+
515+
@pytest.mark.integration
516+
def test_plot_xY_ribbon_fill_kwargs_eti(synthetic_posterior_data):
517+
"""Ribbon ETI path uses fill_kwargs and default label when label is None."""
518+
x, Y = synthetic_posterior_data
519+
fig, ax = plt.subplots()
520+
h_line, h_patch = plot_xY(
521+
x,
522+
Y,
523+
ax=ax,
524+
kind="ribbon",
525+
ci_kind="eti",
526+
plot_hdi_kwargs={
527+
"color": "C2",
528+
"fill_kwargs": {"color": "C2", "alpha": 0.4},
529+
},
530+
label=None,
531+
)
532+
assert isinstance(h_line, plt.Line2D)
533+
assert h_patch is not None
534+
plt.close(fig)

0 commit comments

Comments
 (0)