diff --git a/CHANGELOG.md b/CHANGELOG.md index 287b8127..0e77733c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). ## [Unreleased] ### Fixed +- fixed Quick2D/Quick1D issues where collapsing unused dims did not work - wt5 explore : fixed bug where data will not load interactively if directory is not cwd - constants in chopped data will inherit the units of the original data diff --git a/WrightTools/__citation__.py b/WrightTools/__citation__.py index d8ff1c61..f4083d01 100644 --- a/WrightTools/__citation__.py +++ b/WrightTools/__citation__.py @@ -6,6 +6,6 @@ here = pathlib.Path(__file__).parent -with here / "CITATION" as f: +with open(str(here / "CITATION")) as f: # remove extra whitespace - __citation__ = " ".join(f.read_text().split()) + __citation__ = " ".join(f.read().split()) diff --git a/WrightTools/artists/_interact.py b/WrightTools/artists/_interact.py index 071ab554..583b6ba2 100644 --- a/WrightTools/artists/_interact.py +++ b/WrightTools/artists/_interact.py @@ -217,7 +217,9 @@ def interact2D( if nsliders < 0: raise DimensionalityError(">= 2", data.ndim) # TODO: implement aspect; doesn't work currently because of our incorporation of colorbar - fig, gs = create_figure(width="single", nrows=7 + nsliders, cols=[1, 1, 1, 1, 1, "cbar"]) + fig, gs = create_figure( + width="single", margin=[0.2, 1, 0.2, 1], nrows=7 + nsliders, cols=[1, 1, 1, 1, 1, "cbar"] + ) plt.get_current_fig_manager().set_window_title(f"interact2D: {data.natural_name}") # create axes ax0 = plt.subplot(gs[1:6, 0:5]) diff --git a/WrightTools/artists/_quick.py b/WrightTools/artists/_quick.py index a08abf70..26e436a3 100644 --- a/WrightTools/artists/_quick.py +++ b/WrightTools/artists/_quick.py @@ -34,7 +34,7 @@ def quick1D( autosave=False, save_directory=None, fname=None, - verbose=True + verbose=True, ): """Quickly plot 1D slice(s) of data. @@ -65,14 +65,15 @@ def quick1D( list of strings List of saved image files (if any). """ - # channel index channel_index = wt_kit.get_index(data.channel_names, channel) shape = data.channels[channel_index].shape - collapse = [i for i in range(len(shape)) if shape[i] == 1] - at = at.copy() - at.update({c: 0 for c in collapse}) + # remove dimensions that do not involve the channel + channel_slice = [0 if size == 1 else slice(None, None) for size in shape] + sliced_constants = [ + data.axis_expressions[i] for i in range(len(shape)) if not channel_slice[i] + ] # prepare data - with closing(data.chop(axis, at=at, verbose=False)) as chopped: + with closing(data._from_slice(channel_slice).chop(axis, at=at, verbose=False)) as chopped: # prepare figure fig = None if len(chopped) > 10: @@ -132,18 +133,19 @@ def quick1D( plt.xticks(rotation=45) plt.axvline(0, lw=2, c="k") plt.xlim(xi.min(), xi.max()) - # add constants to title + # constants: variable marker lines, title ls = [] for constant in d.constants: + if constant.expression in sliced_constants: + # ignore these constants; no relation to the data + continue ls.append(constant.label) - title = ", ".join(ls) - _title(fig, data.natural_name, subtitle=title) - # variable marker lines - for constant in d.constants: if constant.units is not None: if axis.units_kind == constant.units_kind: constant.convert(axis.units) plt.axvline(constant.value, color="k", linewidth=4, alpha=0.25) + title = ", ".join(ls) + _title(fig, data.natural_name, subtitle=title) # save -------------------------------------------------------------------------------- if autosave: if fname: @@ -175,7 +177,7 @@ def quick2D( autosave=False, save_directory=None, fname=None, - verbose=True + verbose=True, ): """Quickly plot 2D slice(s) of data. @@ -223,21 +225,14 @@ def quick2D( # channel index channel_index = wt_kit.get_index(data.channel_names, channel) shape = data.channels[channel_index].shape - collapse = [i for i in range(len(shape)) if shape[i] == 1] - at = at.copy() - at.update({c: 0 for c in collapse}) - # prepare data - with closing(data.chop(xaxis, yaxis, at=at, verbose=False)) as chopped: - # colormap - # get colormap - if cmap is None: - if data.channels[channel_index].signed: - cmap = "signed" - else: - cmap = "default" - cmap = colormaps[cmap] - cmap.set_bad([0.75] * 3, 1.0) - cmap.set_under([0.75] * 3, 1.0) + # remove axes that are independent of channel + channel_slice = [0 if size == 1 else slice(None, None) for size in shape] + sliced_constants = [ + data.axis_expressions[i] for i in range(len(shape)) if not channel_slice[i] + ] + with closing( + data._from_slice(channel_slice).chop(xaxis, yaxis, at=at, verbose=False) + ) as chopped: # fname if fname is None: fname = data.natural_name @@ -344,14 +339,13 @@ def quick2D( # add zero lines plt.axvline(0, lw=2, c="k") plt.axhline(0, lw=2, c="k") - # add constants to title + # constants: variable marker lines, title ls = [] for constant in d.constants: + if constant.expression in sliced_constants: + # ignore these constants; no relation to the data + continue ls.append(constant.label) - title = ", ".join(ls) - _title(fig, data.natural_name, subtitle=title) - # variable marker lines - for constant in d.constants: if constant.units is not None: # x axis if xaxis.units_kind == constant.units_kind: @@ -361,6 +355,8 @@ def quick2D( if yaxis.units_kind == constant.units_kind: constant.convert(yaxis.units) plt.axhline(constant.value, color="k", linewidth=4, alpha=0.25) + title = ", ".join(ls) + _title(fig, data.natural_name, subtitle=title) # colorbar cax = plt.subplot(gs[1]) cbar_ticks = np.linspace(levels.min(), levels.max(), 11) diff --git a/setup.cfg b/setup.cfg index ce686c39..13803823 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,7 +24,6 @@ add-ignore = D105 description_file = README.rst license_file = LICENSE.txt - [tool:pytest] addopts = --durations=10 --cov=WrightTools --verbose --cov-report term:skip-covered python_files = tests/*.py diff --git a/tests/artists/test_quick1D.py b/tests/artists/test_quick1D.py index 55358188..ceb6b752 100755 --- a/tests/artists/test_quick1D.py +++ b/tests/artists/test_quick1D.py @@ -30,10 +30,26 @@ def test_2D(): wt.artists.quick1D(data) +def test_moment_channel(): + w1 = np.linspace(-2, 2, 51) + w2 = np.linspace(-1, 1, 3) + w3 = np.linspace(1, 3, 5) + signal = np.cos(w1[:, None, None] + w2[None, :, None] + w3[None, None, :]) + data = wt.data.Data(name="data") + data.create_channel("signal", values=signal, signed=True) + data.create_variable("w1", values=w1[:, None, None], units="wn", label="1") + data.create_variable("w2", values=w2[None, :, None], units="wn", label="2") + data.create_variable("w3", values=w3[None, None, :], units="wn", label="3") + data.transform("w1", "w2", "w3") + data.moment(2, 0, 0) + wt.artists.quick1D(data, channel=-1) + + if __name__ == "__main__": import matplotlib.pyplot as plt plt.close("all") test_perovskite() test_2D() + test_moment_channel() plt.show() diff --git a/tests/artists/test_quick2D.py b/tests/artists/test_quick2D.py index e3a87e7e..b63ce0af 100755 --- a/tests/artists/test_quick2D.py +++ b/tests/artists/test_quick2D.py @@ -39,10 +39,26 @@ def test_4D(): wt.artists.quick2D(data, xaxis=0, yaxis=1) +def test_moment_channel(): + w1 = np.linspace(-2, 2, 51) + w2 = np.linspace(-1, 1, 11) + w3 = np.linspace(1, 3, 5) + signal = np.cos(w1[:, None, None] + w2[None, :, None] + w3[None, None, :]) + data = wt.data.Data(name="data") + data.create_channel("signal", values=signal, signed=True) + data.create_variable("w1", values=w1[:, None, None], units="wn", label="1") + data.create_variable("w2", values=w2[None, :, None], units="wn", label="2") + data.create_variable("w3", values=w3[None, None, :], units="wn", label="3") + data.transform("w1", "w2", "w3") + data.moment(2, 0, 0) + wt.artists.quick2D(data, channel=-1) + + if __name__ == "__main__": import matplotlib.pyplot as plt plt.close("all") test_perovskite() test_4D() + test_moment_channel() plt.show() diff --git a/tests/data/from_PyCMDS.py b/tests/data/from_PyCMDS.py index 8c97e857..8b0f0d8e 100755 --- a/tests/data/from_PyCMDS.py +++ b/tests/data/from_PyCMDS.py @@ -162,7 +162,16 @@ def test_centers_tolerance(): def test_remote(): - data = wt.data.from_PyCMDS("https://osf.io/rdn7v/download") + i = 0 + while True: + # sometimes doesn't work, so try a few times + try: + data = wt.data.from_PyCMDS("https://osf.io/rdn7v/download") + break + except FileNotFoundError as e: + if i == 5: + raise e + i += 1 assert data.shape == (21, 81) assert data.axis_expressions == ("wm", "w2=w1") data.close()