Skip to content

Commit

Permalink
compare figures instead of images (#236)
Browse files Browse the repository at this point in the history
* compare figures instead of images

this is more robust to changes in mpl-styling

* more test updates

* update gitignore for new tests
  • Loading branch information
ianhi authored Mar 5, 2022
1 parent 16e8f0d commit 4ecd1b5
Show file tree
Hide file tree
Showing 12 changed files with 67 additions and 79 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,6 @@ _build
autoapi

_version.py

# mpl testing
result_images/
18 changes: 18 additions & 0 deletions tests/_util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
__all__ = [
"set_param_values",
]


def set_param_values(controls, params):
"""
A bit sketch because it set the index for ipywidgets
and direct value for mpl sliders. big TODO there.
"""
for p, v in params.items():
slider = controls.controls[p]
if "Box" in str(slider.__class__):
for obj in slider.children:
if "Slider" in str(obj.__class__):
obj.value = v
else:
slider.set_val(v)
Binary file removed tests/baseline/test_heatmap_slicer.png
Binary file not shown.
Binary file removed tests/baseline/test_heatmap_slicer32.png
Binary file not shown.
Binary file removed tests/baseline/test_hist_controls.png
Binary file not shown.
Binary file removed tests/baseline/test_hist_plot.png
Binary file not shown.
Binary file removed tests/baseline/test_image_segmentation.png
Binary file not shown.
Binary file removed tests/baseline/test_mixed_types.png
Binary file not shown.
Binary file removed tests/baseline/test_multiple_functions.png
Binary file not shown.
Binary file removed tests/baseline/test_styling.png
Binary file not shown.
12 changes: 1 addition & 11 deletions tests/test_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,11 @@

import matplotlib.pyplot as plt
import numpy as np
import pytest
from matplotlib import __version__ as mpl_version
from packaging import version

from mpl_interactions.generic import heatmap_slicer, image_segmenter

if version.parse(mpl_version) >= version.parse("3.3"):
mplsuffix = ""
else:
mplsuffix = 32


@pytest.mark.mpl_image_compare(style="default", filename=f"test_heatmap_slicer{mplsuffix}.png")
# just smoketests here. hadn't set image comparison styling properly
def test_heatmap_slicer():
x = np.linspace(0, np.pi, 100)
y = np.linspace(0, 10, 200)
Expand All @@ -31,10 +23,8 @@ def test_heatmap_slicer():
interaction_type="move",
cmap="plasma",
)
return fig


@pytest.mark.mpl_image_compare(style="default")
def test_image_segmentation():
image = plt.imread(
"https://github.com/matplotlib/matplotlib/raw/v3.3.0/lib/matplotlib/mpl-data/sample_data/ada.png"
Expand Down
113 changes: 45 additions & 68 deletions tests/test_pyplot.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import matplotlib.pyplot as plt
import numpy as np
import pytest
from matplotlib import __version__ as mpl_version
from matplotlib.testing.decorators import check_figures_equal
from packaging import version

import mpl_interactions.ipyplot as iplt
from mpl_interactions.pyplot import interactive_hist, interactive_plot
from mpl_interactions.utils import figure
from mpl_interactions.pyplot import interactive_plot

from ._util import set_param_values

np.random.seed(1111111121)

Expand All @@ -17,23 +18,11 @@ def f_hist(loc, scale):
return np.random.randn(1000) * scale + loc


@pytest.mark.mpl_image_compare(style="default")
def test_hist_plot():
fig = figure(2)
_ = interactive_hist(f_hist, density=True, loc=(5.5, 100), scale=(10, 15))
fig.tight_layout()
return fig


@pytest.mark.mpl_image_compare(style="default")
def test_hist_controls():
if not mpl_gr_32:
pytest.skip("wonky font differences")
fig, ax = plt.subplots()
controls = interactive_hist(
f_hist, density=True, loc=(5.5, 100), scale=(10, 15), slider_formats="{:.1f}"
)
return controls.control_figures[0]
# # smoke test
# def test_hist_plot(fig_test, fig_ref):
# fig, ax =
# test_ax = fig_test.add_subplot()
# _ = interactive_hist(f_hist, density=True, loc=(5.5, 100), scale=(10, 15), ax=test_ax)


def f1(x, tau, beta):
Expand All @@ -44,30 +33,6 @@ def f2(x, tau, beta):
return np.sin(x * beta) * x * tau


@pytest.mark.mpl_image_compare(style="default")
def test_mixed_types():
if not mpl_gr_32:
pytest.skip("wonky font differences")

def foo(x, **kwargs):
return x

x = np.linspace(0, 1)
a = np.linspace(0, 10)
b = (0, 10, 15)
# set order is determined in part by PYTHONHASHSEED
# but there doesn't seem to be an easy way to set this for pytest
# so the unordered set will change its order from test to test :/
# c = {'this', 'set will be', 'unordered'}
d = {("this", "set will be", "ordered")}
e = 0 # this will not get a slider

# can't test ipywidgets yet
# no mpl widgets for booleans
# f = widgets.Checkbox(value=True, description='A checkbox!!')
return interactive_plot(x, foo, a=a, b=b, d=d, e=e, display=False).control_figures[0]


def f1(x, tau, beta):
return np.sin(x * tau) * x * beta

Expand All @@ -81,7 +46,6 @@ def f2(x, tau, beta):
beta = (1, 2)


@pytest.mark.mpl_image_compare(style="default")
def test_multiple_functions():
fig, ax = plt.subplots()
controls = interactive_plot(x, f1, tau=tau, beta=beta, label="f1")
Expand All @@ -90,35 +54,48 @@ def test_multiple_functions():
return fig


@pytest.mark.mpl_image_compare(style="default")
def test_styling():
fig, ax = plt.subplots()
controls = interactive_plot(
x,
f1,
beta=beta,
tau=tau,
label="f1",
)
iplt.title("the value of tau is: {tau:.2f}", controls=controls["tau"])
@check_figures_equal(extensions=["png"])
def test_plot(fig_test, fig_ref):
test_ax = fig_test.add_subplot()

# TODO: fix the horrible ylim scaling
# get it outside of the plot command
ylims = (-10, 10)
controls = interactive_plot(x, f1, beta=beta, tau=tau, label="f1", ax=test_ax, ylim=ylims)
interactive_plot(
x,
f2,
controls=controls,
label="custom label!",
linestyle="--",
x, f2, controls=controls, label="custom label!", linestyle="--", ax=test_ax, ylim=ylims
)
plt.legend()
return fig
set_param_values(controls, {"beta": 5, "tau": 4})
test_ax.legend()

ref_ax = fig_ref.add_subplot()
ref_ax.plot(x, f1(x, **controls.params), label="f1")
ref_ax.plot(x, f2(x, **controls.params), linestyle="--", label="custom label!")
ref_ax.legend()
ref_ax.set_ylim(ylims)
for fig in controls.control_figures:
plt.close(fig)

def test_imshow_scalars():

@check_figures_equal(extensions=["png"])
def test_imshow_scalars(fig_test, fig_ref):
# and by proxy all the scalar handling
def mask(min_distance):
return np.random.randn(10, 10)

fig, ax = plt.subplots()
iplt.imshow(mask, min_distance=(1, 10), alpha=(0, 1))
mask_arr = np.random.randn(10, 10) * 10

def mask(min_distance):
new_arr = np.copy(mask_arr)
new_arr[mask_arr < min_distance] = 0
return new_arr

test_ax = fig_test.add_subplot()
ctrls = iplt.imshow(mask, min_distance=(1, 10), alpha=(0, 1), ax=test_ax)
set_param_values(ctrls, {"min_distance": 5.5, "alpha": 0.75})
ref_ax = fig_ref.add_subplot()
print(ctrls.params)
ref_ax.imshow(mask(ctrls.params["min_distance"]), alpha=ctrls.params["alpha"])
for fig in ctrls.control_figures:
plt.close(fig)


def test_title():
Expand Down

0 comments on commit 4ecd1b5

Please sign in to comment.