From dc75772cc0c0673ddb49f78a2d6e890d831e68da Mon Sep 17 00:00:00 2001 From: ShaunD137 Date: Fri, 10 Jul 2026 17:19:39 +0100 Subject: [PATCH 01/32] initial commit of voxel plotting --- src/sdf_xarray/dataarray_accessor.py | 163 +++++++++++++++++- src/sdf_xarray/plotting.py | 240 ++++++++++++++++++++++++++- 2 files changed, 388 insertions(+), 15 deletions(-) diff --git a/src/sdf_xarray/dataarray_accessor.py b/src/sdf_xarray/dataarray_accessor.py index 2377105..9abde5e 100644 --- a/src/sdf_xarray/dataarray_accessor.py +++ b/src/sdf_xarray/dataarray_accessor.py @@ -3,14 +3,46 @@ from types import MethodType from typing import TYPE_CHECKING +import numpy as np import xarray as xr from xarray.plot.accessor import DataArrayPlotAccessor -from .plotting import animate, show +from .plotting import animate, show, voxel_plot, _recover_vertex_coord if TYPE_CHECKING: from matplotlib.animation import FuncAnimation +def _resize_ndarray( + arr: np.ndarray, + new_shape: tuple | list | np.ndarray, +) -> np.ndarray: + """ + Resizes a `numpy.ndarray` to another shape. The returned array must have the + same dimensionality as the input array. + Parameters + ---------- + arr + The input array. + new_shape + The shape of the new `xarray.DataArray`, must be the same length as arr.shape. + """ + + from scipy.interpolate import RegularGridInterpolator # noqa: PLC0415 + + if arr.ndim != len(new_shape): + raise ValueError( + f"The number of dimensions must match the input array. (original: {arr.ndim}, new: {len(new_shape)})" + ) + + old_grids = tuple(np.linspace(0, 1, size) for size in arr.shape) + new_grids = tuple(np.linspace(0, 1, size) for size in new_shape) + mesh = np.meshgrid(*new_grids, indexing="ij") + coords = np.stack(mesh, axis=-1) + + return RegularGridInterpolator(old_grids, arr, bounds_error=False, fill_value=0)( + coords + ) + @xr.register_dataarray_accessor("epoch") class EpochAccessor: @@ -35,18 +67,21 @@ def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: Keyword arguments passed to `xarray.DataArray.plot`. """ dims = self._obj.dims - is_not_2d_data = len(dims) != 2 - is_time_dim_present = "time" in dims - is_x_or_y_specified_in_kwargs = "x" in kwargs or "y" in kwargs - if is_not_2d_data or is_time_dim_present or is_x_or_y_specified_in_kwargs: + if len(dims) == 1: return self._obj.plot(*args, **kwargs) + + elif len(dims) == 2: + updated_kwargs = dict(kwargs) + updated_kwargs.setdefault("x", dims[0]) + updated_kwargs.setdefault("y", dims[1]) + return self._obj.plot(*args, **updated_kwargs) - updated_kwargs = dict(kwargs) - updated_kwargs.setdefault("x", dims[0]) - updated_kwargs.setdefault("y", dims[1]) + elif len(dims) == 3: + return voxel_plot(self._obj, *args, **kwargs) - return self._obj.plot(*args, **updated_kwargs) + else: + return self._obj.plot(*args, **kwargs) def animate(self, *args, **kwargs) -> FuncAnimation: """Generate animations of Epoch data. @@ -72,3 +107,113 @@ def animate(self, *args, **kwargs) -> FuncAnimation: anim.show = MethodType(show, anim) return anim + + + def resize( + self, + new_shape, + ) -> xr.DataArray: + """ + Resizes a `xarray.DataArray` to another shape. The returned array must have the + same dimensionality as the input array. + + Parameters + ---------- + new_shape + The shape of the new `xarray.DataArray`, must be the same length as self.shape. + """ + + da = self._obj + + # Create resized data and Dataset + data_resized = _resize_ndarray(da.values, new_shape) + da_resized = da.copy() + da_resized = xr.DataArray( + data=data_resized, + dims=da.dims, + attrs=da.attrs, + ) + + original_cell_size_da = [] + + # Resize coordinates and add to DataArray + for i in range(len(da_resized.dims)): + coord = list(da_resized.dims)[i] + + if coord[-4:] == "_mid": + # If the coordinate is a midpoint coordinate, care must be taken to resize correctly + vertex_coord = _recover_vertex_coord(da[coord]) + vertex_coord_resized = np.linspace(vertex_coord[0], vertex_coord[-1], new_shape[i]+1) + # Turn the vertex coord back into a midpoint coord + da_resized[coord] = ((np.roll(vertex_coord_resized, 1) + vertex_coord_resized)/2)[1:] + else: + # If not, the coordinate can be simply resized + coord_min = da[coord][0].values + coord_max = da[coord][-1].values + da_resized[coord] = np.linspace(coord_min, coord_max, new_shape[i]) + + da_resized[coord].attrs = da[coord].attrs + + # Add original information as attributes + if "original_shape" not in da.attrs: + da_resized[coord].attrs["original_size"] = da.shape[i] + original_cell_size = float((da[coord][1] - da[coord][0]).values) + original_cell_size_da.append(original_cell_size) + da_resized[coord].attrs["original_cell_size"] = original_cell_size + + if "original_shape" not in da.attrs: + da_resized.attrs["original_shape"] = da.shape + da_resized.attrs["original_cell_size"] = tuple(original_cell_size_da) + + return da_resized + + + def limit( + self, + limits, + drop:bool = True, + ) -> xr.DataArray: + """ + Drops values outside the specified limits. + + Parameters + ---------- + limits + Array-like list of limits. + drop + Bool specifying whether to drop the co-ordinates outside the limits (default = True). + """ + da = self._obj + limits = list(limits) + + # List of dimension names + dims = da.dims + + original_lims_da = [] + for i in range(len(dims)): + limits[i] = list(limits[i]) + + # Find the original limits of the dataarray + original_lims = ( + float(da[dims[i]].values[0]), + float(da[dims[i]].values[-1]) + ) + original_lims_da.append(original_lims) + if "original_lims" not in da[dims[i]].attrs: + da[dims[i]].attrs["original_lims"] = original_lims + + # If None is passed into limit, will assume the existing limit + if limits[i][0] == None: + limits[i][0] = original_lims[0] + if limits[i][-1] == None: + limits[i][-1] = original_lims[1] + + # Limit dataarray + da = da.where( + da[dims[i]] >= limits[i][0], drop = drop).where( + da[dims[i]] <= limits[i][1], drop = drop) + + if "original_lims" not in da.attrs: + da.attrs["original_lims"] = tuple(original_lims_da) + + return da \ No newline at end of file diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index 723b6e4..e8cfd97 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -56,6 +56,47 @@ def get_frame_title( return f"{title_custom}{title_t_axis}{title_sdf}" +def get_axis_label(dim: xr.DataArray): + label = f"{dim.long_name} [{dim.units}]" + return label + + +def _recover_vertex_coord(w_mid): + # Takes a midpoint coordinate, returns a vertex coordinate + w_size = w_mid.size + dw = w_mid[1] - w_mid[0] + w = np.zeros(w_mid.size + 1) + w[:w_size] = w_mid - dw/2 + w[w_size] = w[w_size-1] + dw + return w + + +def shift_cmap(cmap, vmin, vmax, vcenter, N=1024): + """ + Creates a new colourmap where the visual center of the original + colourmap is shifted to a specific data value. + """ + import matplotlib.pyplot as plt + import matplotlib.colors as mc + + # get the original colourmap + if type(cmap) == str: + cmap = plt.get_cmap(cmap) + + midpoint = (vcenter - vmin) / (vmax - vmin) + lower_size = int(N * midpoint) + upper_size = N - lower_size + + bottom_colors = cmap(np.linspace(0.0, 0.5, lower_size)) + top_colors = cmap(np.linspace(0.5, 1.0, upper_size)) + new_colors = np.vstack((bottom_colors, top_colors)) + + new_cmap = mc.ListedColormap(new_colors, name=f"shifted_{cmap.name}") + + return new_cmap + + + def calculate_window_boundaries( data: xr.DataArray, xlim: tuple[float, float] | None = None, @@ -135,7 +176,142 @@ def _set_axes_labels(ax: plt.Axes, axis_kwargs: dict) -> None: ax.set_ylabel(axis_kwargs["ylabel"]) -def _setup_2d_plot( +def voxel_plot( + da, + vmin = None, + vmax = None, + vcenter = None, + mask = None, + xlim = (None, None), + ylim = (None, None), + zlim = (None, None), + aspect = "equal", + elev = 30, + azim = -60, + cmap = "viridis", + cbar_scale = 0.9, + ): + """ + Will take 3 dimensional data and plot it as voxels. + + Parameters + ---------- + da + DataArray to be plotted. + vmin + Minimum value. If `mask` is not stated, will be used to define the mask. + vmax + Maximum value. If `mask` is not stated, will be used to define the mask. + vcenter + Center value of the colourmap. Useful for diverging colourmaps with non-symetrical data. + mask + Array of bools specifing which cells to show. Must be same size as `da` + xlim, ylim, zlim + Sets the limits of the plot. + aspect + Aspect ratio of the plot. "equal", "auto" or list of floats. (default = "equal") + elev + Elevation angle in degrees. (default = 30) + azim + Azimithul angle in degrees. (default = -60) + cmap + Colourmap (default = "viridis") + cbar_scale + Vertical scale of the colorbar (default = 0.9) + """ + import matplotlib.pyplot as plt + + print("Warning! voxel plots can be extremely intensive!") + + # Limit arrays based on axis limits + da = da.epoch.limit((xlim, ylim, zlim)) + + dims = da.dims + + # Create W_Grid from W_Grid_mid coords + x = _recover_vertex_coord(da[dims[0]]) + y = _recover_vertex_coord(da[dims[1]]) + z = _recover_vertex_coord(da[dims[2]]) + + # Create mesh + x_mesh, y_mesh, z_mesh = np.meshgrid(x, y, z, indexing="ij") + + if vmin == None: + vmin = np.min(da.values) + if vmax == None: + vmax = np.max(da.values) + + # Mask out data + if mask == None: + mask = (da > vmin) * (da < vmax) + + # Plot the data array + fig = plt.figure(figsize=(8, 6)) + ax = fig.add_subplot(projection='3d') + ax.view_init(elev, azim) + + # Set axis labels + ax.set_xlabel(get_axis_label(da[dims[0]])) + ax.set_ylabel(get_axis_label(da[dims[1]])) + ax.set_zlabel(get_axis_label(da[dims[2]])) + + # Find axis limits + xlim = list(xlim) + ylim = list(ylim) + zlim = list(zlim) + if xlim[0] == None: + xlim[0] = x.min() + if xlim[1] == None: + xlim[1] = x.max() + if ylim[0] == None: + ylim[0] = y.min() + if ylim[1] == None: + ylim[1] = y.max() + if zlim[0] == None: + zlim[0] = z.min() + if zlim[1] == None: + zlim[1] = z.max() + + # Set aspect ratio of plot + if aspect == "equal": + x_aspect = 1 + y_aspect = 1 + z_aspect = 1 + elif aspect == "auto": + x_aspect = xlim[1] - xlim[0] + y_aspect = ylim[1] - ylim[0] + z_aspect = zlim[1] - zlim[0] + else: + x_aspect, y_aspect, z_aspect = aspect + ax.set_box_aspect((x_aspect, y_aspect, z_aspect)) + + # Limit axis of plot + ax.set_xlim(xlim[0], xlim[1]) + ax.set_ylim(ylim[0], ylim[1]) + ax.set_zlim(zlim[0], zlim[1]) + + # Colour bar and colour map + if vcenter is not None: + cmap = shift_cmap(cmap, vmin, vmax, vcenter) + norm = plt.Normalize(vmin = vmin, vmax = vmax) + cmap = plt.get_cmap(cmap) + colours = cmap(norm(da)) + + sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm) + sm.set_array([]) # Required for the colorbar to function + cbar_label = get_axis_label(da) + fig.colorbar(sm, ax=ax, label=cbar_label, shrink = cbar_scale, aspect = 20*cbar_scale) + + ax.voxels( + x_mesh, y_mesh, z_mesh, + mask, + facecolors = colours, + ) + + return fig, ax + + +def _setup_line_plot( data: xr.DataArray, ax: plt.Axes, coord_names: list[str], @@ -145,7 +321,7 @@ def _setup_2d_plot( max_percentile: float, t: str, ) -> tuple[float, float]: - """Setup 2D plot initialization.""" + """Line animation initialization.""" kwargs.setdefault("x", coord_names[0]) @@ -161,7 +337,43 @@ def _setup_2d_plot( return global_min, global_max -def _setup_3d_plot( +def _setup_pcolormesh_plot( + data: xr.DataArray, + ax: plt.Axes, + coord_names: list[str], + kwargs: dict, + kwargs_original: dict, + axis_kwargs: dict, + min_percentile: float, + max_percentile: float, + t: str, +) -> None: + """pcolormesh animation initialization.""" + import matplotlib.pyplot as plt # noqa: PLC0415 + + if "norm" not in kwargs: + global_min, global_max = compute_global_limits( + data, min_percentile, max_percentile + ) + kwargs["norm"] = plt.Normalize(vmin=global_min, vmax=global_max) + + kwargs["add_colorbar"] = False + kwargs.setdefault("x", coord_names[0]) + kwargs.setdefault("y", coord_names[1]) + + argmin_time = np.unravel_index(np.argmin(data.values), data.shape)[0] + plot = data.isel({t: argmin_time}).plot(ax=ax, **kwargs) + kwargs["cmap"] = plot.cmap + + _set_axes_labels(ax, axis_kwargs) + + if kwargs_original.get("add_colorbar", True): + long_name = data.attrs.get("long_name") + units = data.attrs.get("units") + fig = plot.get_figure() + fig.colorbar(plot, ax=ax, label=f"{long_name} [{units}]") + +def _setup_voxel_plot( data: xr.DataArray, ax: plt.Axes, coord_names: list[str], @@ -172,7 +384,10 @@ def _setup_3d_plot( max_percentile: float, t: str, ) -> None: - """Setup 3D plot initialization.""" + """ + Voxel animation initialization. + NOTE: this function exists for completeness, voxel plots don't work in animations yet + """ import matplotlib.pyplot as plt # noqa: PLC0415 if "norm" not in kwargs: @@ -262,7 +477,7 @@ def _generate_animation( global_min = global_max = None if data.ndim == 2: - global_min, global_max = _setup_2d_plot( + global_min, global_max = _setup_line_plot( data=data, ax=ax, coord_names=coord_names, @@ -273,7 +488,7 @@ def _generate_animation( t=t, ) elif data.ndim == 3: - _setup_3d_plot( + _setup_pcolormesh_plot( data=data, ax=ax, coord_names=coord_names, @@ -284,6 +499,19 @@ def _generate_animation( max_percentile=max_percentile, t=t, ) + elif data.ndim == 4: + raise NotImplementedError("Voxel animations are not currently supported.") + # _setup_voxel_plot( + # data=data, + # ax=ax, + # coord_names=coord_names, + # kwargs=kwargs, + # kwargs_original=kwargs_original, + # axis_kwargs=axis_kwargs, + # min_percentile=min_percentile, + # max_percentile=max_percentile, + # t=t, + # ) ax.set_title(get_frame_title(data, 0, display_sdf_name, title, t)) From 26d20ce0c664576aacd394353159400162d1b748 Mon Sep 17 00:00:00 2001 From: JoelLucaAdams Date: Sat, 11 Jul 2026 13:18:39 +0100 Subject: [PATCH 02/32] Add missing scipy dependency to docs and tests --- pyproject.toml | 2 + uv.lock | 141 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 33b9c35..039d3c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,6 +69,7 @@ docs = [ "sphinx-design>=0.7.0", "pooch>=1.8.2", "tqdm", + "scipy", ] build = ["cibuildwheel[uv]"] lint = ["ruff"] @@ -80,6 +81,7 @@ test = [ "tqdm", "pint", "pint-xarray", + "scipy", ] [project.entry-points."xarray.backends"] diff --git a/uv.lock b/uv.lock index 99d7307..1a4d309 100644 --- a/uv.lock +++ b/uv.lock @@ -2246,6 +2246,134 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c4/1c/1dbe51782c0e1e9cfce1d1004752672d2d4629ea46945d19d731ad772b3b/ruff-0.14.11-py3-none-win_arm64.whl", hash = "sha256:649fb6c9edd7f751db276ef42df1f3df41c38d67d199570ae2a7bd6cbc3590f0", size = 12938644, upload-time = "2026-01-08T19:11:50.027Z" }, ] +[[package]] +name = "scipy" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.12'", +] +dependencies = [ + { name = "numpy", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/75/b4ce781849931fef6fd529afa6b63711d5a733065722d0c3e2724af9e40a/scipy-1.17.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:1f95b894f13729334fb990162e911c9e5dc1ab390c58aa6cbecb389c5b5e28ec", size = 31613675, upload-time = "2026-02-23T00:16:00.13Z" }, + { url = "https://files.pythonhosted.org/packages/f7/58/bccc2861b305abdd1b8663d6130c0b3d7cc22e8d86663edbc8401bfd40d4/scipy-1.17.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:e18f12c6b0bc5a592ed23d3f7b891f68fd7f8241d69b7883769eb5d5dfb52696", size = 28162057, upload-time = "2026-02-23T00:16:09.456Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ee/18146b7757ed4976276b9c9819108adbc73c5aad636e5353e20746b73069/scipy-1.17.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a3472cfbca0a54177d0faa68f697d8ba4c80bbdc19908c3465556d9f7efce9ee", size = 20334032, upload-time = "2026-02-23T00:16:17.358Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e6/cef1cf3557f0c54954198554a10016b6a03b2ec9e22a4e1df734936bd99c/scipy-1.17.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:766e0dc5a616d026a3a1cffa379af959671729083882f50307e18175797b3dfd", size = 22709533, upload-time = "2026-02-23T00:16:25.791Z" }, + { url = "https://files.pythonhosted.org/packages/4d/60/8804678875fc59362b0fb759ab3ecce1f09c10a735680318ac30da8cd76b/scipy-1.17.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:744b2bf3640d907b79f3fd7874efe432d1cf171ee721243e350f55234b4cec4c", size = 33062057, upload-time = "2026-02-23T00:16:36.931Z" }, + { url = "https://files.pythonhosted.org/packages/09/7d/af933f0f6e0767995b4e2d705a0665e454d1c19402aa7e895de3951ebb04/scipy-1.17.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43af8d1f3bea642559019edfe64e9b11192a8978efbd1539d7bc2aaa23d92de4", size = 35349300, upload-time = "2026-02-23T00:16:49.108Z" }, + { url = "https://files.pythonhosted.org/packages/b4/3d/7ccbbdcbb54c8fdc20d3b6930137c782a163fa626f0aef920349873421ba/scipy-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd96a1898c0a47be4520327e01f874acfd61fb48a9420f8aa9f6483412ffa444", size = 35127333, upload-time = "2026-02-23T00:17:01.293Z" }, + { url = "https://files.pythonhosted.org/packages/e8/19/f926cb11c42b15ba08e3a71e376d816ac08614f769b4f47e06c3580c836a/scipy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4eb6c25dd62ee8d5edf68a8e1c171dd71c292fdae95d8aeb3dd7d7de4c364082", size = 37741314, upload-time = "2026-02-23T00:17:12.576Z" }, + { url = "https://files.pythonhosted.org/packages/95/da/0d1df507cf574b3f224ccc3d45244c9a1d732c81dcb26b1e8a766ae271a8/scipy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:d30e57c72013c2a4fe441c2fcb8e77b14e152ad48b5464858e07e2ad9fbfceff", size = 36607512, upload-time = "2026-02-23T00:17:23.424Z" }, + { url = "https://files.pythonhosted.org/packages/68/7f/bdd79ceaad24b671543ffe0ef61ed8e659440eb683b66f033454dcee90eb/scipy-1.17.1-cp311-cp311-win_arm64.whl", hash = "sha256:9ecb4efb1cd6e8c4afea0daa91a87fbddbce1b99d2895d151596716c0b2e859d", size = 24599248, upload-time = "2026-02-23T00:17:34.561Z" }, + { url = "https://files.pythonhosted.org/packages/35/48/b992b488d6f299dbe3f11a20b24d3dda3d46f1a635ede1c46b5b17a7b163/scipy-1.17.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:35c3a56d2ef83efc372eaec584314bd0ef2e2f0d2adb21c55e6ad5b344c0dcb8", size = 31610954, upload-time = "2026-02-23T00:17:49.855Z" }, + { url = "https://files.pythonhosted.org/packages/b2/02/cf107b01494c19dc100f1d0b7ac3cc08666e96ba2d64db7626066cee895e/scipy-1.17.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:fcb310ddb270a06114bb64bbe53c94926b943f5b7f0842194d585c65eb4edd76", size = 28172662, upload-time = "2026-02-23T00:18:01.64Z" }, + { url = "https://files.pythonhosted.org/packages/cf/a9/599c28631bad314d219cf9ffd40e985b24d603fc8a2f4ccc5ae8419a535b/scipy-1.17.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:cc90d2e9c7e5c7f1a482c9875007c095c3194b1cfedca3c2f3291cdc2bc7c086", size = 20344366, upload-time = "2026-02-23T00:18:12.015Z" }, + { url = "https://files.pythonhosted.org/packages/35/f5/906eda513271c8deb5af284e5ef0206d17a96239af79f9fa0aebfe0e36b4/scipy-1.17.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:c80be5ede8f3f8eded4eff73cc99a25c388ce98e555b17d31da05287015ffa5b", size = 22704017, upload-time = "2026-02-23T00:18:21.502Z" }, + { url = "https://files.pythonhosted.org/packages/da/34/16f10e3042d2f1d6b66e0428308ab52224b6a23049cb2f5c1756f713815f/scipy-1.17.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e19ebea31758fac5893a2ac360fedd00116cbb7628e650842a6691ba7ca28a21", size = 32927842, upload-time = "2026-02-23T00:18:35.367Z" }, + { url = "https://files.pythonhosted.org/packages/01/8e/1e35281b8ab6d5d72ebe9911edcdffa3f36b04ed9d51dec6dd140396e220/scipy-1.17.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458", size = 35235890, upload-time = "2026-02-23T00:18:49.188Z" }, + { url = "https://files.pythonhosted.org/packages/c5/5c/9d7f4c88bea6e0d5a4f1bc0506a53a00e9fcb198de372bfe4d3652cef482/scipy-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a604bae87c6195d8b1045eddece0514d041604b14f2727bbc2b3020172045eb", size = 35003557, upload-time = "2026-02-23T00:18:54.74Z" }, + { url = "https://files.pythonhosted.org/packages/65/94/7698add8f276dbab7a9de9fb6b0e02fc13ee61d51c7c3f85ac28b65e1239/scipy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f590cd684941912d10becc07325a3eeb77886fe981415660d9265c4c418d0bea", size = 37625856, upload-time = "2026-02-23T00:19:00.307Z" }, + { url = "https://files.pythonhosted.org/packages/a2/84/dc08d77fbf3d87d3ee27f6a0c6dcce1de5829a64f2eae85a0ecc1f0daa73/scipy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:41b71f4a3a4cab9d366cd9065b288efc4d4f3c0b37a91a8e0947fb5bd7f31d87", size = 36549682, upload-time = "2026-02-23T00:19:07.67Z" }, + { url = "https://files.pythonhosted.org/packages/bc/98/fe9ae9ffb3b54b62559f52dedaebe204b408db8109a8c66fdd04869e6424/scipy-1.17.1-cp312-cp312-win_arm64.whl", hash = "sha256:f4115102802df98b2b0db3cce5cb9b92572633a1197c77b7553e5203f284a5b3", size = 24547340, upload-time = "2026-02-23T00:19:12.024Z" }, + { url = "https://files.pythonhosted.org/packages/76/27/07ee1b57b65e92645f219b37148a7e7928b82e2b5dbeccecb4dff7c64f0b/scipy-1.17.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5e3c5c011904115f88a39308379c17f91546f77c1667cea98739fe0fccea804c", size = 31590199, upload-time = "2026-02-23T00:19:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f", size = 28154001, upload-time = "2026-02-23T00:19:22.241Z" }, + { url = "https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d", size = 20325719, upload-time = "2026-02-23T00:19:26.329Z" }, + { url = "https://files.pythonhosted.org/packages/b2/83/15087d945e0e4d48ce2377498abf5ad171ae013232ae31d06f336e64c999/scipy-1.17.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4b400bdc6f79fa02a4d86640310dde87a21fba0c979efff5248908c6f15fad1b", size = 22683595, upload-time = "2026-02-23T00:19:30.304Z" }, + { url = "https://files.pythonhosted.org/packages/b4/e0/e58fbde4a1a594c8be8114eb4aac1a55bcd6587047efc18a61eb1f5c0d30/scipy-1.17.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b64ca7d4aee0102a97f3ba22124052b4bd2152522355073580bf4845e2550b6", size = 32896429, upload-time = "2026-02-23T00:19:35.536Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464", size = 35203952, upload-time = "2026-02-23T00:19:42.259Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a5/9afd17de24f657fdfe4df9a3f1ea049b39aef7c06000c13db1530d81ccca/scipy-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:beeda3d4ae615106d7094f7e7cef6218392e4465cc95d25f900bebabfded0950", size = 34979063, upload-time = "2026-02-23T00:19:47.547Z" }, + { url = "https://files.pythonhosted.org/packages/8b/13/88b1d2384b424bf7c924f2038c1c409f8d88bb2a8d49d097861dd64a57b2/scipy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6609bc224e9568f65064cfa72edc0f24ee6655b47575954ec6339534b2798369", size = 37598449, upload-time = "2026-02-23T00:19:53.238Z" }, + { url = "https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448", size = 36510943, upload-time = "2026-02-23T00:20:50.89Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fd/3be73c564e2a01e690e19cc618811540ba5354c67c8680dce3281123fb79/scipy-1.17.1-cp313-cp313-win_arm64.whl", hash = "sha256:5cf36e801231b6a2059bf354720274b7558746f3b1a4efb43fcf557ccd484a87", size = 24545621, upload-time = "2026-02-23T00:20:55.871Z" }, + { url = "https://files.pythonhosted.org/packages/6f/6b/17787db8b8114933a66f9dcc479a8272e4b4da75fe03b0c282f7b0ade8cd/scipy-1.17.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:d59c30000a16d8edc7e64152e30220bfbd724c9bbb08368c054e24c651314f0a", size = 31936708, upload-time = "2026-02-23T00:19:58.694Z" }, + { url = "https://files.pythonhosted.org/packages/38/2e/524405c2b6392765ab1e2b722a41d5da33dc5c7b7278184a8ad29b6cb206/scipy-1.17.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0", size = 28570135, upload-time = "2026-02-23T00:20:03.934Z" }, + { url = "https://files.pythonhosted.org/packages/fd/c3/5bd7199f4ea8556c0c8e39f04ccb014ac37d1468e6cfa6a95c6b3562b76e/scipy-1.17.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:2ceb2d3e01c5f1d83c4189737a42d9cb2fc38a6eeed225e7515eef71ad301dce", size = 20741977, upload-time = "2026-02-23T00:20:07.935Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b8/8ccd9b766ad14c78386599708eb745f6b44f08400a5fd0ade7cf89b6fc93/scipy-1.17.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:844e165636711ef41f80b4103ed234181646b98a53c8f05da12ca5ca289134f6", size = 23029601, upload-time = "2026-02-23T00:20:12.161Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a0/3cb6f4d2fb3e17428ad2880333cac878909ad1a89f678527b5328b93c1d4/scipy-1.17.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:158dd96d2207e21c966063e1635b1063cd7787b627b6f07305315dd73d9c679e", size = 33019667, upload-time = "2026-02-23T00:20:17.208Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c3/2d834a5ac7bf3a0c806ad1508efc02dda3c8c61472a56132d7894c312dea/scipy-1.17.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74cbb80d93260fe2ffa334efa24cb8f2f0f622a9b9febf8b483c0b865bfb3475", size = 35264159, upload-time = "2026-02-23T00:20:23.087Z" }, + { url = "https://files.pythonhosted.org/packages/4d/77/d3ed4becfdbd217c52062fafe35a72388d1bd82c2d0ba5ca19d6fcc93e11/scipy-1.17.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dbc12c9f3d185f5c737d801da555fb74b3dcfa1a50b66a1a93e09190f41fab50", size = 35102771, upload-time = "2026-02-23T00:20:28.636Z" }, + { url = "https://files.pythonhosted.org/packages/bd/12/d19da97efde68ca1ee5538bb261d5d2c062f0c055575128f11a2730e3ac1/scipy-1.17.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94055a11dfebe37c656e70317e1996dc197e1a15bbcc351bcdd4610e128fe1ca", size = 37665910, upload-time = "2026-02-23T00:20:34.743Z" }, + { url = "https://files.pythonhosted.org/packages/06/1c/1172a88d507a4baaf72c5a09bb6c018fe2ae0ab622e5830b703a46cc9e44/scipy-1.17.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e30bdeaa5deed6bc27b4cc490823cd0347d7dae09119b8803ae576ea0ce52e4c", size = 36562980, upload-time = "2026-02-23T00:20:40.575Z" }, + { url = "https://files.pythonhosted.org/packages/70/b0/eb757336e5a76dfa7911f63252e3b7d1de00935d7705cf772db5b45ec238/scipy-1.17.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a720477885a9d2411f94a93d16f9d89bad0f28ca23c3f8daa521e2dcc3f44d49", size = 24856543, upload-time = "2026-02-23T00:20:45.313Z" }, + { url = "https://files.pythonhosted.org/packages/cf/83/333afb452af6f0fd70414dc04f898647ee1423979ce02efa75c3b0f2c28e/scipy-1.17.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:a48a72c77a310327f6a3a920092fa2b8fd03d7deaa60f093038f22d98e096717", size = 31584510, upload-time = "2026-02-23T00:21:01.015Z" }, + { url = "https://files.pythonhosted.org/packages/ed/a6/d05a85fd51daeb2e4ea71d102f15b34fedca8e931af02594193ae4fd25f7/scipy-1.17.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:45abad819184f07240d8a696117a7aacd39787af9e0b719d00285549ed19a1e9", size = 28170131, upload-time = "2026-02-23T00:21:05.888Z" }, + { url = "https://files.pythonhosted.org/packages/db/7b/8624a203326675d7746a254083a187398090a179335b2e4a20e2ddc46e83/scipy-1.17.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3fd1fcdab3ea951b610dc4cef356d416d5802991e7e32b5254828d342f7b7e0b", size = 20342032, upload-time = "2026-02-23T00:21:09.904Z" }, + { url = "https://files.pythonhosted.org/packages/c9/35/2c342897c00775d688d8ff3987aced3426858fd89d5a0e26e020b660b301/scipy-1.17.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7bdf2da170b67fdf10bca777614b1c7d96ae3ca5794fd9587dce41eb2966e866", size = 22678766, upload-time = "2026-02-23T00:21:14.313Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f2/7cdb8eb308a1a6ae1e19f945913c82c23c0c442a462a46480ce487fdc0ac/scipy-1.17.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:adb2642e060a6549c343603a3851ba76ef0b74cc8c079a9a58121c7ec9fe2350", size = 32957007, upload-time = "2026-02-23T00:21:19.663Z" }, + { url = "https://files.pythonhosted.org/packages/0b/2e/7eea398450457ecb54e18e9d10110993fa65561c4f3add5e8eccd2b9cd41/scipy-1.17.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eee2cfda04c00a857206a4330f0c5e3e56535494e30ca445eb19ec624ae75118", size = 35221333, upload-time = "2026-02-23T00:21:25.278Z" }, + { url = "https://files.pythonhosted.org/packages/d9/77/5b8509d03b77f093a0d52e606d3c4f79e8b06d1d38c441dacb1e26cacf46/scipy-1.17.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d2650c1fb97e184d12d8ba010493ee7b322864f7d3d00d3f9bb97d9c21de4068", size = 35042066, upload-time = "2026-02-23T00:21:31.358Z" }, + { url = "https://files.pythonhosted.org/packages/f9/df/18f80fb99df40b4070328d5ae5c596f2f00fffb50167e31439e932f29e7d/scipy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:08b900519463543aa604a06bec02461558a6e1cef8fdbb8098f77a48a83c8118", size = 37612763, upload-time = "2026-02-23T00:21:37.247Z" }, + { url = "https://files.pythonhosted.org/packages/4b/39/f0e8ea762a764a9dc52aa7dabcfad51a354819de1f0d4652b6a1122424d6/scipy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:3877ac408e14da24a6196de0ddcace62092bfc12a83823e92e49e40747e52c19", size = 37290984, upload-time = "2026-02-23T00:22:35.023Z" }, + { url = "https://files.pythonhosted.org/packages/7c/56/fe201e3b0f93d1a8bcf75d3379affd228a63d7e2d80ab45467a74b494947/scipy-1.17.1-cp314-cp314-win_arm64.whl", hash = "sha256:f8885db0bc2bffa59d5c1b72fad7a6a92d3e80e7257f967dd81abb553a90d293", size = 25192877, upload-time = "2026-02-23T00:22:39.798Z" }, + { url = "https://files.pythonhosted.org/packages/96/ad/f8c414e121f82e02d76f310f16db9899c4fcde36710329502a6b2a3c0392/scipy-1.17.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:1cc682cea2ae55524432f3cdff9e9a3be743d52a7443d0cba9017c23c87ae2f6", size = 31949750, upload-time = "2026-02-23T00:21:42.289Z" }, + { url = "https://files.pythonhosted.org/packages/7c/b0/c741e8865d61b67c81e255f4f0a832846c064e426636cd7de84e74d209be/scipy-1.17.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:2040ad4d1795a0ae89bfc7e8429677f365d45aa9fd5e4587cf1ea737f927b4a1", size = 28585858, upload-time = "2026-02-23T00:21:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1b/3985219c6177866628fa7c2595bfd23f193ceebbe472c98a08824b9466ff/scipy-1.17.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:131f5aaea57602008f9822e2115029b55d4b5f7c070287699fe45c661d051e39", size = 20757723, upload-time = "2026-02-23T00:21:52.039Z" }, + { url = "https://files.pythonhosted.org/packages/c0/19/2a04aa25050d656d6f7b9e7b685cc83d6957fb101665bfd9369ca6534563/scipy-1.17.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9cdc1a2fcfd5c52cfb3045feb399f7b3ce822abdde3a193a6b9a60b3cb5854ca", size = 23043098, upload-time = "2026-02-23T00:21:56.185Z" }, + { url = "https://files.pythonhosted.org/packages/86/f1/3383beb9b5d0dbddd030335bf8a8b32d4317185efe495374f134d8be6cce/scipy-1.17.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e3dcd57ab780c741fde8dc68619de988b966db759a3c3152e8e9142c26295ad", size = 33030397, upload-time = "2026-02-23T00:22:01.404Z" }, + { url = "https://files.pythonhosted.org/packages/41/68/8f21e8a65a5a03f25a79165ec9d2b28c00e66dc80546cf5eb803aeeff35b/scipy-1.17.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9956e4d4f4a301ebf6cde39850333a6b6110799d470dbbb1e25326ac447f52a", size = 35281163, upload-time = "2026-02-23T00:22:07.024Z" }, + { url = "https://files.pythonhosted.org/packages/84/8d/c8a5e19479554007a5632ed7529e665c315ae7492b4f946b0deb39870e39/scipy-1.17.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a4328d245944d09fd639771de275701ccadf5f781ba0ff092ad141e017eccda4", size = 35116291, upload-time = "2026-02-23T00:22:12.585Z" }, + { url = "https://files.pythonhosted.org/packages/52/52/e57eceff0e342a1f50e274264ed47497b59e6a4e3118808ee58ddda7b74a/scipy-1.17.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a77cbd07b940d326d39a1d1b37817e2ee4d79cb30e7338f3d0cddffae70fcaa2", size = 37682317, upload-time = "2026-02-23T00:22:18.513Z" }, + { url = "https://files.pythonhosted.org/packages/11/2f/b29eafe4a3fbc3d6de9662b36e028d5f039e72d345e05c250e121a230dd4/scipy-1.17.1-cp314-cp314t-win_amd64.whl", hash = "sha256:eb092099205ef62cd1782b006658db09e2fed75bffcae7cc0d44052d8aa0f484", size = 37345327, upload-time = "2026-02-23T00:22:24.442Z" }, + { url = "https://files.pythonhosted.org/packages/07/39/338d9219c4e87f3e708f18857ecd24d22a0c3094752393319553096b98af/scipy-1.17.1-cp314-cp314t-win_arm64.whl", hash = "sha256:200e1050faffacc162be6a486a984a0497866ec54149a01270adc8a59b7c7d21", size = 25489165, upload-time = "2026-02-23T00:22:29.563Z" }, +] + +[[package]] +name = "scipy" +version = "1.18.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.12'", +] +dependencies = [ + { name = "numpy", marker = "python_full_version >= '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/25/c2700dfaf6442b4effaa91af24ebce5dc9d31bb4a69706313aae70d72cd0/scipy-1.18.0.tar.gz", hash = "sha256:67b2ad2ad54c72ca6d04975a9b2df8c3638c34ddd5b28738e94fc2b57929d378", size = 30774447, upload-time = "2026-06-19T15:01:43.456Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/19/ca10ead60b0acc80b2b833c2c4a4f2ff753d0f58b811f70d911c7e94a25c/scipy-1.18.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:7bd21faaf5a1a3b2eff922d02db5f191b99a6518db9078a8fb23169f6d22259a", size = 31056519, upload-time = "2026-06-19T14:59:45.203Z" }, + { url = "https://files.pythonhosted.org/packages/96/72/1e6442a00cd2924d361aa1b642ab6373ec35c6fabf311a760be9f76e0f13/scipy-1.18.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:265915e79107de9f946b855e50d7470d5893ec3f54b342e1aa6201cbdcd8bb6b", size = 28681889, upload-time = "2026-06-19T14:59:48.103Z" }, + { url = "https://files.pythonhosted.org/packages/9b/2d/11dd93d21e147a73ba22bd75c0b9208d3a2e0ec76d53170ce7d9029b1015/scipy-1.18.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9ab7b758be6940954a713ee466e2043e9f6e2ed965c1fce5c91039f4be3d90a9", size = 20423580, upload-time = "2026-06-19T14:59:50.665Z" }, + { url = "https://files.pythonhosted.org/packages/9c/01/93552f75e0d2a7dd115a45e59209c51e8d514daff02fc887d2623be06fe1/scipy-1.18.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:97b6cddaaee0a779ef6b5ca83c9604b27cc16b2b8fc22c142652df8793319fb8", size = 23054441, upload-time = "2026-06-19T14:59:53.564Z" }, + { url = "https://files.pythonhosted.org/packages/3c/23/21f5e703643d66f21faa6b4c73195bfcad70c55efcb4f1ab327cd7c4101a/scipy-1.18.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:52a96e21517c7292375c0e27dd796a811f03fcea5fd4d108fdfea8145dcf17ab", size = 33968720, upload-time = "2026-06-19T14:59:56.415Z" }, + { url = "https://files.pythonhosted.org/packages/dd/aa/1b939f6c67ed68635bb538e6752d3dacc02f66535182e939a89581a44e9c/scipy-1.18.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f55797419e16e7f30cf88ffb3113ce0467f00cfe3f70d5c281730b21769bfc2", size = 35287115, upload-time = "2026-06-19T14:59:59.411Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ff/eec46be7e9234208f801062b53e1983085eddebd693f6c9bfb03b459830d/scipy-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ad033410e2e0672ffdc1042110cef20e1c46f8fd0616cee1d44d8d58fad8fc11", size = 35577989, upload-time = "2026-06-19T15:00:02.235Z" }, + { url = "https://files.pythonhosted.org/packages/84/ca/210d4759c7210bb7d269437421959b39a33434e2776b60c5cb8a763bb30a/scipy-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a55985d54c769c872e64b7f4c8a81cc30ef700cc04296abbbf3705439c126de", size = 37421717, upload-time = "2026-06-19T15:00:05.102Z" }, + { url = "https://files.pythonhosted.org/packages/2b/54/9a9edb45345bd6744da5ddfb6628e5d5185920494c6a67ec45b6381004cb/scipy-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:71ccc8faa2dd16ac310233203474a8b5cb67f10dedd54a3116d34943f4b19132", size = 36597428, upload-time = "2026-06-19T15:00:08.112Z" }, + { url = "https://files.pythonhosted.org/packages/99/0e/33f32a2a58987e26aec0f7df252cbbad1e90ae77bdbc76f40dd4ed0cf0ea/scipy-1.18.0-cp312-cp312-win_arm64.whl", hash = "sha256:d88363fd9d8fbd3511bd273f1a49efb2a540773ddf92a91d57498ce7dd7f3e76", size = 24351481, upload-time = "2026-06-19T15:00:11.103Z" }, + { url = "https://files.pythonhosted.org/packages/05/52/9c0136c2de7ae0779b7b366447766cec6d9f0702c56bb8ffeb04c8fd3af4/scipy-1.18.0-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:09143f676d157d9f546d663504ef9c1becb819824f1afc018814176411942446", size = 31036107, upload-time = "2026-06-19T15:00:14.03Z" }, + { url = "https://files.pythonhosted.org/packages/02/73/0291a64843270f4efb86cdcf2ee0f2048631b65ec6b405398b2b4dbf11bf/scipy-1.18.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5efe260f69417b97ddae455bfb5a95e8359f7f66ad7fa9522a60feb66f169520", size = 28663303, upload-time = "2026-06-19T15:00:16.819Z" }, + { url = "https://files.pythonhosted.org/packages/d3/0f/10ffa0b697a572f4e0d48b92a88895d366422f019f723e7e14a84c050dac/scipy-1.18.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:68363b7eaacd8b5dd426df56d782cc156468ac79a127a1b87ca597d6e2e82197", size = 20404960, upload-time = "2026-06-19T15:00:19.635Z" }, + { url = "https://files.pythonhosted.org/packages/7e/d2/e896cea21ba8edd6c81d4c55b1ffcc717e79698dcbebf9641b4cfb4c6622/scipy-1.18.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:c5557d8be5da8e41353fcd4d21491fdbab83b062fc579e94dc09a7c8ab4f669b", size = 23034074, upload-time = "2026-06-19T15:00:22.107Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b2/e83ea34279a52c03374477c74006256ec78df65fc877baa4617d6de1d202/scipy-1.18.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0d13bca67c096d89fb95ced0d8921807300fce0275643aef9533cc63a0773468", size = 33942038, upload-time = "2026-06-19T15:00:24.964Z" }, + { url = "https://files.pythonhosted.org/packages/f6/af/e8fe5fb136f51e2b01678b92cb4106d10d8cd68ec147ead2e7cb0ac75398/scipy-1.18.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a46f9273dbd0eb1cefba61c9b8648b4dfe3cbc14a080176f9a73e44b8336dc7f", size = 35266390, upload-time = "2026-06-19T15:00:28.059Z" }, + { url = "https://files.pythonhosted.org/packages/3a/49/2c5cbb907b56695fc67517811d1db234dfd83381a84814ec220aded2794d/scipy-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5aba46108853ddfc77906b6557aac839d2b52e900c1d72a1180adaaab58d265f", size = 35551324, upload-time = "2026-06-19T15:00:31.014Z" }, + { url = "https://files.pythonhosted.org/packages/bb/73/eda39f7a2d306ff0ffc574afd13c0bbb6d10a603d9a413998ee269487a80/scipy-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b6f758e35f12757b5d95c00bc6de2438e229c2664b7a92e96f205959d9f2dfa4", size = 37404785, upload-time = "2026-06-19T15:00:34.072Z" }, + { url = "https://files.pythonhosted.org/packages/b7/d2/ae881ee28d014f38e0ccbfd974a06a919ba9af34f1f74bf42b5301891d63/scipy-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1afac4a847207c7ff8efd321734a50b06d0280b3b2a2c0fc2f413101747ad7c7", size = 36554943, upload-time = "2026-06-19T15:00:36.903Z" }, + { url = "https://files.pythonhosted.org/packages/70/3a/21154e2d54eb3639c6bf4dbae2e531c68356bfe95990daa30df33b30d556/scipy-1.18.0-cp313-cp313-win_arm64.whl", hash = "sha256:c5dbddf60e58c2312316d097271a8e73d40eaf2eabfa4d95ed7d3695bbf2ce7b", size = 24350911, upload-time = "2026-06-19T15:00:40.062Z" }, + { url = "https://files.pythonhosted.org/packages/78/b5/915a19b3de2f7430062b509653563db1633ddbb6f021b06731521115d4e2/scipy-1.18.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4c256ee70c0d1a8a2ace807e199ccd4e3f57037433842abb3fb36bc17eaa9578", size = 31036253, upload-time = "2026-06-19T15:00:43.216Z" }, + { url = "https://files.pythonhosted.org/packages/d7/88/b72def7262e150d16be13fca37a96481138d624e700340bc3362a7588929/scipy-1.18.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:2ef3abc54a4ffc53765374b0d5728532dfdd2585ed23f6b11c206a1f0b1b9af8", size = 28673758, upload-time = "2026-06-19T15:00:46.663Z" }, + { url = "https://files.pythonhosted.org/packages/91/02/2e636a61a525632c373cf6a9c24442a3ffb79e364d38e98b32042964ac32/scipy-1.18.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f2a6af57bd9e4a75d70e4117e78a1bbee84f79ae3fbb6d0111005d6ebcc4cb8d", size = 20415514, upload-time = "2026-06-19T15:00:49.399Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b6/2135974442f6aba159d9d39d774a1c8cb19947016725d69fecc685df45bf/scipy-1.18.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:3f1ac564d3bf6c03d861d2cd87a1bea0da2887136f7fb1bf519c05a8971452d6", size = 23034398, upload-time = "2026-06-19T15:00:51.941Z" }, + { url = "https://files.pythonhosted.org/packages/f6/e6/ba89ec5abf6ee9257c0d1ec985573f3ae32742c24bc03e016388a40b1b15/scipy-1.18.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40395a5fcd1abee49a5c7aaa98c29db393eedc835138560a588c47ec16156690", size = 33998032, upload-time = "2026-06-19T15:00:54.838Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/bc41eb19b0fd0db868f4132920879019318d80cc522ad8f2bca4611af808/scipy-1.18.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ca01e8ae69f1b18e9a58d91afead31be3cef0dd905a10249dac559ee15460a0", size = 35283333, upload-time = "2026-06-19T15:00:58.152Z" }, + { url = "https://files.pythonhosted.org/packages/53/a4/cbdeef6eb3830a8462a9d4ada814de5fc984345cc9ecf17cbec51a036f1e/scipy-1.18.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7a7f3b01647384dbc3a711e8c6778e0aabbe93959249fef5c7393396bcac0867", size = 35610216, upload-time = "2026-06-19T15:01:01.155Z" }, + { url = "https://files.pythonhosted.org/packages/80/4d/b2b82502b65f661d1b789c1665dcdf315d5f12194e06fc0b37946294ebae/scipy-1.18.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6aa94e78ec192a30063a5e72e561c28af769dc311190b24fe91774eff1969709", size = 37418960, upload-time = "2026-06-19T15:01:04.155Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/902d836831474b0ab5a37d16404f7bc5fafd9efba632890e271ba952635f/scipy-1.18.0-cp314-cp314-win_amd64.whl", hash = "sha256:2d8bbdc6c817f5b4006a54d799d4f5bab6f910193cbb9a1ff310833d4d270f61", size = 37288845, upload-time = "2026-06-19T15:01:07.822Z" }, + { url = "https://files.pythonhosted.org/packages/b6/43/8d73b337a3bdb14daa0314f0434210747c02d79d729ce1777574a817dcf6/scipy-1.18.0-cp314-cp314-win_arm64.whl", hash = "sha256:18e9575f1569b2c54174e6159d32942e03731177f63dce7975f0a0c88d102f5b", size = 24988971, upload-time = "2026-06-19T15:01:11.076Z" }, + { url = "https://files.pythonhosted.org/packages/b4/b4/f11918b0508a2787031a0499a03fbe3546f3bb5ca05d01038c45b278c09a/scipy-1.18.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f351e0dd702687d12a402b867a1b4146a256923e1c38317cbc472f6372b94707", size = 31399325, upload-time = "2026-06-19T15:01:13.723Z" }, + { url = "https://files.pythonhosted.org/packages/7b/d1/1f287b57c0ff0ee5185dff3946d92c8017d39b0e431f0ae79a3ff1859512/scipy-1.18.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7c7a51b33ce387193c97f228320cf8e87361daa1bba750638677729598b3e677", size = 29092110, upload-time = "2026-06-19T15:01:16.908Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1a/7b74eb6c392fdcb27d414c0e7558a6d0231eb3b6d73571f479bb81ea8794/scipy-1.18.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:84031d7b052a54fae2f8632e0ec802073d385476eb9a63079bce6e23ef9283d4", size = 20833811, upload-time = "2026-06-19T15:01:20.488Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ad/f3941716320a7b9cb4d68734a903b45fe16eff5fb7da7e16f2e619304979/scipy-1.18.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:56abf29a7c067dde59be8b9a22d606a4ea1b2f2a4b756d9d903c62818f5dacce", size = 23396644, upload-time = "2026-06-19T15:01:23.364Z" }, + { url = "https://files.pythonhosted.org/packages/22/22/1446b62ffe07f9719b7d9b1b6a4e05a772833ae8f441fe4c22c34c9b250f/scipy-1.18.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ad44305cfa24b1ba5803cbbebf033590ccbac1aa5d612d727b785325ab408b0", size = 34079318, upload-time = "2026-06-19T15:01:26.002Z" }, + { url = "https://files.pythonhosted.org/packages/56/3b/b87da667098bb470fa30c7011b0ba351ee976dd395c78798c66e941665a3/scipy-1.18.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:945c1761b93f38d7f99ae81ae80c63e621471608c7eeead563f6df025585cd58", size = 35324320, upload-time = "2026-06-19T15:01:28.881Z" }, + { url = "https://files.pythonhosted.org/packages/f8/a1/c7932f91909759b0267f75fdea34e91309f96b895757534b76a90b6b4344/scipy-1.18.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1a4441f15d620578772a49e5ab48c0ee1f7a0220e387110283062729136b2553", size = 35699541, upload-time = "2026-06-19T15:01:31.968Z" }, + { url = "https://files.pythonhosted.org/packages/f7/86/5185061a1fcc41d18c5dc2463969b3a3964b31d9ac67b2fb05d4c7ff7670/scipy-1.18.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9aac6192fac56bf2ca534389d24623f07b39ff83317d58287285e7fbd622ff76", size = 37472480, upload-time = "2026-06-19T15:01:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/31/8e/f04c68e39919a010d34f2ee1367fd705b0a25a02f609d755f0bfbc0a15fc/scipy-1.18.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e40baea28ae7f5475c779741e2d90b1247c78531207b49c7030e698ff81cee3f", size = 37365390, upload-time = "2026-06-19T15:01:38.091Z" }, + { url = "https://files.pythonhosted.org/packages/d5/19/969dc072906c84dd0a3b05dcf57ea750936087d7873549e408b35cfc3f97/scipy-1.18.0-cp314-cp314t-win_arm64.whl", hash = "sha256:368e0a705903c466aa5f08eefb39e6b1b6b2d659e7352a31fd9e2438365be0f8", size = 25279661, upload-time = "2026-06-19T15:01:40.817Z" }, +] + [[package]] name = "sdf-xarray" source = { editable = "." } @@ -2281,6 +2409,8 @@ dev = [ { name = "pooch" }, { name = "pytest" }, { name = "ruff" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "sphinx" }, { name = "sphinx-argparse-cli" }, { name = "sphinx-autobuild" }, @@ -2299,6 +2429,8 @@ docs = [ { name = "pint" }, { name = "pint-xarray" }, { name = "pooch" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "sphinx" }, { name = "sphinx-argparse-cli" }, { name = "sphinx-autobuild" }, @@ -2316,8 +2448,12 @@ lint = [ test = [ { name = "dask", extra = ["complete"] }, { name = "matplotlib" }, + { name = "pint" }, + { name = "pint-xarray" }, { name = "pooch" }, { name = "pytest" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "tqdm" }, ] @@ -2347,6 +2483,7 @@ dev = [ { name = "pooch", specifier = ">=1.8.2" }, { name = "pytest", specifier = ">=3.3.0" }, { name = "ruff" }, + { name = "scipy" }, { name = "sphinx", specifier = ">=5.3" }, { name = "sphinx-argparse-cli", specifier = ">=1.10.0" }, { name = "sphinx-autobuild", specifier = ">=2025.8.25" }, @@ -2365,6 +2502,7 @@ docs = [ { name = "pint" }, { name = "pint-xarray" }, { name = "pooch", specifier = ">=1.8.2" }, + { name = "scipy" }, { name = "sphinx", specifier = ">=5.3" }, { name = "sphinx-argparse-cli", specifier = ">=1.10.0" }, { name = "sphinx-autobuild", specifier = ">=2025.8.25" }, @@ -2380,8 +2518,11 @@ lint = [{ name = "ruff" }] test = [ { name = "dask", extras = ["complete"] }, { name = "matplotlib" }, + { name = "pint" }, + { name = "pint-xarray" }, { name = "pooch", specifier = ">=1.8.2" }, { name = "pytest", specifier = ">=3.3.0" }, + { name = "scipy" }, { name = "tqdm" }, ] From 64da60b0c90f9195e3cbebbe3b3c4b97de7a6b58 Mon Sep 17 00:00:00 2001 From: JoelLucaAdams Date: Sat, 11 Jul 2026 13:31:22 +0100 Subject: [PATCH 03/32] make voxel plotting pass ruff check --- src/sdf_xarray/dataarray_accessor.py | 54 +++++++++-------- src/sdf_xarray/plotting.py | 89 ++++++++++++++-------------- 2 files changed, 72 insertions(+), 71 deletions(-) diff --git a/src/sdf_xarray/dataarray_accessor.py b/src/sdf_xarray/dataarray_accessor.py index 9abde5e..aba2c66 100644 --- a/src/sdf_xarray/dataarray_accessor.py +++ b/src/sdf_xarray/dataarray_accessor.py @@ -7,11 +7,12 @@ import xarray as xr from xarray.plot.accessor import DataArrayPlotAccessor -from .plotting import animate, show, voxel_plot, _recover_vertex_coord +from .plotting import _recover_vertex_coord, animate, show, voxel_plot if TYPE_CHECKING: from matplotlib.animation import FuncAnimation + def _resize_ndarray( arr: np.ndarray, new_shape: tuple | list | np.ndarray, @@ -70,18 +71,17 @@ def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: if len(dims) == 1: return self._obj.plot(*args, **kwargs) - - elif len(dims) == 2: + + if len(dims) == 2: updated_kwargs = dict(kwargs) updated_kwargs.setdefault("x", dims[0]) updated_kwargs.setdefault("y", dims[1]) return self._obj.plot(*args, **updated_kwargs) - elif len(dims) == 3: + if len(dims) == 3: return voxel_plot(self._obj, *args, **kwargs) - else: - return self._obj.plot(*args, **kwargs) + return self._obj.plot(*args, **kwargs) def animate(self, *args, **kwargs) -> FuncAnimation: """Generate animations of Epoch data. @@ -108,11 +108,10 @@ def animate(self, *args, **kwargs) -> FuncAnimation: return anim - def resize( - self, - new_shape, - ) -> xr.DataArray: + self, + new_shape, + ) -> xr.DataArray: """ Resizes a `xarray.DataArray` to another shape. The returned array must have the same dimensionality as the input array. @@ -143,9 +142,13 @@ def resize( if coord[-4:] == "_mid": # If the coordinate is a midpoint coordinate, care must be taken to resize correctly vertex_coord = _recover_vertex_coord(da[coord]) - vertex_coord_resized = np.linspace(vertex_coord[0], vertex_coord[-1], new_shape[i]+1) + vertex_coord_resized = np.linspace( + vertex_coord[0], vertex_coord[-1], new_shape[i] + 1 + ) # Turn the vertex coord back into a midpoint coord - da_resized[coord] = ((np.roll(vertex_coord_resized, 1) + vertex_coord_resized)/2)[1:] + da_resized[coord] = ( + (np.roll(vertex_coord_resized, 1) + vertex_coord_resized) / 2 + )[1:] else: # If not, the coordinate can be simply resized coord_min = da[coord][0].values @@ -154,24 +157,23 @@ def resize( da_resized[coord].attrs = da[coord].attrs - # Add original information as attributes + # Add original information as attributes if "original_shape" not in da.attrs: da_resized[coord].attrs["original_size"] = da.shape[i] original_cell_size = float((da[coord][1] - da[coord][0]).values) original_cell_size_da.append(original_cell_size) da_resized[coord].attrs["original_cell_size"] = original_cell_size - + if "original_shape" not in da.attrs: da_resized.attrs["original_shape"] = da.shape da_resized.attrs["original_cell_size"] = tuple(original_cell_size_da) return da_resized - def limit( self, limits, - drop:bool = True, + drop: bool = True, ) -> xr.DataArray: """ Drops values outside the specified limits. @@ -196,24 +198,24 @@ def limit( # Find the original limits of the dataarray original_lims = ( float(da[dims[i]].values[0]), - float(da[dims[i]].values[-1]) + float(da[dims[i]].values[-1]), ) original_lims_da.append(original_lims) if "original_lims" not in da[dims[i]].attrs: da[dims[i]].attrs["original_lims"] = original_lims # If None is passed into limit, will assume the existing limit - if limits[i][0] == None: - limits[i][0] = original_lims[0] - if limits[i][-1] == None: + if limits[i][0] is None: + limits[i][0] = original_lims[0] + if limits[i][-1] is None: limits[i][-1] = original_lims[1] # Limit dataarray - da = da.where( - da[dims[i]] >= limits[i][0], drop = drop).where( - da[dims[i]] <= limits[i][1], drop = drop) - + da = da.where(da[dims[i]] >= limits[i][0], drop=drop).where( + da[dims[i]] <= limits[i][1], drop=drop + ) + if "original_lims" not in da.attrs: - da.attrs["original_lims"] = tuple(original_lims_da) + da.attrs["original_lims"] = tuple(original_lims_da) - return da \ No newline at end of file + return da diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index e8cfd97..9c6f755 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -57,8 +57,7 @@ def get_frame_title( def get_axis_label(dim: xr.DataArray): - label = f"{dim.long_name} [{dim.units}]" - return label + return f"{dim.long_name} [{dim.units}]" def _recover_vertex_coord(w_mid): @@ -66,35 +65,32 @@ def _recover_vertex_coord(w_mid): w_size = w_mid.size dw = w_mid[1] - w_mid[0] w = np.zeros(w_mid.size + 1) - w[:w_size] = w_mid - dw/2 - w[w_size] = w[w_size-1] + dw + w[:w_size] = w_mid - dw / 2 + w[w_size] = w[w_size - 1] + dw return w def shift_cmap(cmap, vmin, vmax, vcenter, N=1024): """ - Creates a new colourmap where the visual center of the original + Creates a new colourmap where the visual center of the original colourmap is shifted to a specific data value. """ - import matplotlib.pyplot as plt - import matplotlib.colors as mc + import matplotlib.colors as mc # noqa: PLC0415 + import matplotlib.pyplot as plt # noqa: PLC0415 # get the original colourmap - if type(cmap) == str: + if type(cmap) is str: cmap = plt.get_cmap(cmap) - + midpoint = (vcenter - vmin) / (vmax - vmin) lower_size = int(N * midpoint) upper_size = N - lower_size - + bottom_colors = cmap(np.linspace(0.0, 0.5, lower_size)) top_colors = cmap(np.linspace(0.5, 1.0, upper_size)) new_colors = np.vstack((bottom_colors, top_colors)) - - new_cmap = mc.ListedColormap(new_colors, name=f"shifted_{cmap.name}") - - return new_cmap + return mc.ListedColormap(new_colors, name=f"shifted_{cmap.name}") def calculate_window_boundaries( @@ -176,21 +172,21 @@ def _set_axes_labels(ax: plt.Axes, axis_kwargs: dict) -> None: ax.set_ylabel(axis_kwargs["ylabel"]) -def voxel_plot( - da, - vmin = None, - vmax = None, - vcenter = None, - mask = None, - xlim = (None, None), - ylim = (None, None), - zlim = (None, None), - aspect = "equal", - elev = 30, - azim = -60, - cmap = "viridis", - cbar_scale = 0.9, - ): +def voxel_plot( # noqa: PLR0912, PLR0915 + da, + vmin=None, + vmax=None, + vcenter=None, + mask=None, + xlim=(None, None), + ylim=(None, None), + zlim=(None, None), + aspect="equal", + elev=30, + azim=-60, + cmap="viridis", + cbar_scale=0.9, +): """ Will take 3 dimensional data and plot it as voxels. @@ -219,7 +215,7 @@ def voxel_plot( cbar_scale Vertical scale of the colorbar (default = 0.9) """ - import matplotlib.pyplot as plt + import matplotlib.pyplot as plt # noqa: PLC0415 print("Warning! voxel plots can be extremely intensive!") @@ -236,18 +232,18 @@ def voxel_plot( # Create mesh x_mesh, y_mesh, z_mesh = np.meshgrid(x, y, z, indexing="ij") - if vmin == None: + if vmin is None: vmin = np.min(da.values) - if vmax == None: + if vmax is None: vmax = np.max(da.values) # Mask out data - if mask == None: + if mask is None: mask = (da > vmin) * (da < vmax) # Plot the data array fig = plt.figure(figsize=(8, 6)) - ax = fig.add_subplot(projection='3d') + ax = fig.add_subplot(projection="3d") ax.view_init(elev, azim) # Set axis labels @@ -259,17 +255,17 @@ def voxel_plot( xlim = list(xlim) ylim = list(ylim) zlim = list(zlim) - if xlim[0] == None: + if xlim[0] is None: xlim[0] = x.min() - if xlim[1] == None: + if xlim[1] is None: xlim[1] = x.max() - if ylim[0] == None: + if ylim[0] is None: ylim[0] = y.min() - if ylim[1] == None: + if ylim[1] is None: ylim[1] = y.max() - if zlim[0] == None: + if zlim[0] is None: zlim[0] = z.min() - if zlim[1] == None: + if zlim[1] is None: zlim[1] = z.max() # Set aspect ratio of plot @@ -293,19 +289,21 @@ def voxel_plot( # Colour bar and colour map if vcenter is not None: cmap = shift_cmap(cmap, vmin, vmax, vcenter) - norm = plt.Normalize(vmin = vmin, vmax = vmax) + norm = plt.Normalize(vmin=vmin, vmax=vmax) cmap = plt.get_cmap(cmap) colours = cmap(norm(da)) - + sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm) sm.set_array([]) # Required for the colorbar to function cbar_label = get_axis_label(da) - fig.colorbar(sm, ax=ax, label=cbar_label, shrink = cbar_scale, aspect = 20*cbar_scale) + fig.colorbar(sm, ax=ax, label=cbar_label, shrink=cbar_scale, aspect=20 * cbar_scale) ax.voxels( - x_mesh, y_mesh, z_mesh, + x_mesh, + y_mesh, + z_mesh, mask, - facecolors = colours, + facecolors=colours, ) return fig, ax @@ -373,6 +371,7 @@ def _setup_pcolormesh_plot( fig = plot.get_figure() fig.colorbar(plot, ax=ax, label=f"{long_name} [{units}]") + def _setup_voxel_plot( data: xr.DataArray, ax: plt.Axes, From fc398a39338b2f802f57a787e8e05a0677ba1706 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Tue, 14 Jul 2026 16:04:10 +0200 Subject: [PATCH 04/32] Add tests for voxel plot, resize and lims --- tests/test_epoch_dataarray_accessor.py | 240 +++++++++++++++++++++++++ 1 file changed, 240 insertions(+) diff --git a/tests/test_epoch_dataarray_accessor.py b/tests/test_epoch_dataarray_accessor.py index d9b6513..b76f992 100644 --- a/tests/test_epoch_dataarray_accessor.py +++ b/tests/test_epoch_dataarray_accessor.py @@ -7,7 +7,9 @@ import pytest import xarray as xr from matplotlib.animation import PillowWriter +from matplotlib.colors import ListedColormap from matplotlib.container import BarContainer +from mpl_toolkits.mplot3d import Axes3D from packaging.version import Version import sdf_xarray as sdfxr @@ -335,3 +337,241 @@ def test_epoch_plot_flips_axis_order_for_2d_data_but_not_when_time_dim_present( plot = ds["Derived_Number_Density_electron"].epoch.plot(ax=ax) assert type(plot[2]) is BarContainer + + +def _make_3d_da(shape=(4, 5, 6)): + """Small synthetic 3-D DataArray with the metadata voxel_plot expects.""" + nx, ny, nz = shape + rng = np.random.default_rng(42) + data = rng.uniform(0.0, 1.0, (nx, ny, nz)).astype(np.float64) + return xr.DataArray( + data, + dims=["X_Grid_mid", "Y_Grid_mid", "Z_Grid_mid"], + coords={ + "X_Grid_mid": xr.Variable( + "X_Grid_mid", + np.linspace(0.0, 1e-5, nx), + attrs={"long_name": "X", "units": "m"}, + ), + "Y_Grid_mid": xr.Variable( + "Y_Grid_mid", + np.linspace(0.0, 2e-5, ny), + attrs={"long_name": "Y", "units": "m"}, + ), + "Z_Grid_mid": xr.Variable( + "Z_Grid_mid", + np.linspace(0.0, 3e-5, nz), + attrs={"long_name": "Z", "units": "m"}, + ), + }, + attrs={"long_name": "Test Density", "units": "1/m^3"}, + ) + + +@pytest.fixture +def close_figs(): + yield + plt.close("all") + + +def test_recover_vertex_coord_size(): + mid = xr.DataArray(np.linspace(0.5, 4.5, 5)) + vertex = sxp._recover_vertex_coord(mid) + assert vertex.size == mid.size + 1 + + +def test_recover_vertex_coord_values(): + mid = xr.DataArray(np.array([0.5, 1.5, 2.5])) + vertex = sxp._recover_vertex_coord(mid) + np.testing.assert_allclose(vertex, [0.0, 1.0, 2.0, 3.0]) + + +def test_shift_cmap_returns_listed_colormap(): + result = sxp.shift_cmap("RdBu", vmin=-1.0, vmax=1.0, vcenter=0.0) + assert isinstance(result, ListedColormap) + + +def test_shift_cmap_total_colors(): + result = sxp.shift_cmap("RdBu", vmin=-1.0, vmax=1.0, vcenter=0.0, N=100) + assert len(result.colors) == 100 + + +def test_shift_cmap_asymmetric_center(): + result = sxp.shift_cmap("viridis", vmin=0.0, vmax=1.0, vcenter=0.25, N=200) + assert isinstance(result, ListedColormap) + assert len(result.colors) == 200 + + +def test_voxel_plot_returns_fig_and_ax(close_figs): + da = _make_3d_da() + fig, ax = sxp.voxel_plot(da) + assert isinstance(ax, Axes3D) + + +def test_voxel_plot_axis_labels(close_figs): + da = _make_3d_da() + _, ax = sxp.voxel_plot(da) + assert ax.get_xlabel() == "X [m]" + assert ax.get_ylabel() == "Y [m]" + assert ax.get_zlabel() == "Z [m]" + + +def test_voxel_plot_default_axis_limits(close_figs): + da = _make_3d_da() + _, ax = sxp.voxel_plot(da) + xlim = ax.get_xlim() + ylim = ax.get_ylim() + zlim = ax.get_zlim() + assert xlim[0] < xlim[1] + assert ylim[0] < ylim[1] + assert zlim[0] < zlim[1] + + +def test_voxel_plot_with_xlim_ylim_zlim(close_figs): + da = _make_3d_da() + x0, x1 = 2e-6, 8e-6 + y0, y1 = 2e-6, 1.8e-5 + z0, z1 = 5e-6, 2.5e-5 + _, ax = sxp.voxel_plot(da, xlim=(x0, x1), ylim=(y0, y1), zlim=(z0, z1)) + assert ax.get_xlim() == pytest.approx((x0, x1), rel=0.1) + assert ax.get_ylim() == pytest.approx((y0, y1), rel=0.1) + assert ax.get_zlim() == pytest.approx((z0, z1), rel=0.1) + + +def test_voxel_plot_with_explicit_vmin_vmax(close_figs): + da = _make_3d_da() + fig, ax = sxp.voxel_plot(da, vmin=0.2, vmax=0.8) + assert isinstance(ax, Axes3D) + + +def test_voxel_plot_with_vcenter(close_figs): + da = _make_3d_da() + fig, ax = sxp.voxel_plot(da, cmap="RdBu", vcenter=1e-2) + assert isinstance(ax, Axes3D) + + +def test_voxel_plot_with_custom_mask(close_figs): + da = _make_3d_da() + mask = da.values > 0.5 + fig, ax = sxp.voxel_plot(da, mask=mask) + assert isinstance(ax, Axes3D) + + +def test_voxel_plot_aspect_auto(close_figs): + da = _make_3d_da() + _, ax = sxp.voxel_plot(da, aspect="auto") + box = ax.get_box_aspect() + # voxel_plot uses vertex coords (half-cell beyond midpoints) for axis ranges; + # matplotlib normalizes the absolute values, so only ratios are stable + x_vert = sxp._recover_vertex_coord(da["X_Grid_mid"]) + y_vert = sxp._recover_vertex_coord(da["Y_Grid_mid"]) + z_vert = sxp._recover_vertex_coord(da["Z_Grid_mid"]) + x_range = x_vert.max() - x_vert.min() + y_range = y_vert.max() - y_vert.min() + z_range = z_vert.max() - z_vert.min() + assert box[1] / box[0] == pytest.approx(y_range / x_range, rel=0.05) + assert box[2] / box[0] == pytest.approx(z_range / x_range, rel=0.05) + + +def test_voxel_plot_aspect_custom_tuple(close_figs): + da = _make_3d_da() + _, ax = sxp.voxel_plot(da, aspect=(1.0, 2.0, 3.0)) + box = ax.get_box_aspect() + assert box[1] / box[0] == pytest.approx(2.0, rel=0.01) + assert box[2] / box[0] == pytest.approx(3.0, rel=0.01) + + +def test_epoch_plot_dispatches_to_voxel_for_3d_spatial_data(close_figs): + with xr.open_dataset(TEST_FILES_DIR_3D / "0001.sdf") as ds: + da = ds["Derived_Number_Density_Electron"].isel( + X_Grid_mid=slice(0, 4), + Y_Grid_mid=slice(0, 4), + Z_Grid_mid=slice(0, 4), + ) + fig, ax = da.epoch.plot() + assert isinstance(ax, Axes3D) + assert ax.get_xlabel() == "X [m]" + assert ax.get_ylabel() == "Y [m]" + assert ax.get_zlabel() == "Z [m]" + + +def test_resize_basic(): + da = _make_3d_da(shape=(8, 10, 12)) + da_small = da.epoch.resize((4, 5, 6)) + assert da_small.shape == (4, 5, 6) + assert da_small.dims == da.dims + + +def test_resize_stores_original_shape_attrs(): + da = _make_3d_da(shape=(8, 10, 12)) + da_small = da.epoch.resize((4, 5, 6)) + assert da_small.attrs["original_shape"] == (8, 10, 12) + + +def test_resize_coord_range_preserved(): + da = _make_3d_da(shape=(8, 10, 12)) + da_small = da.epoch.resize((4, 5, 6)) + # For _mid coords, resize preserves the vertex (cell-edge) range rather than + # the midpoint values; check that the outer vertices are unchanged + orig_vertex = sxp._recover_vertex_coord(da["X_Grid_mid"]) + new_vertex = sxp._recover_vertex_coord(da_small["X_Grid_mid"]) + np.testing.assert_allclose(float(new_vertex[0]), float(orig_vertex[0]), rtol=1e-6) + np.testing.assert_allclose(float(new_vertex[-1]), float(orig_vertex[-1]), rtol=1e-6) + + +def test_resize_wrong_ndim_raises(): + da = _make_3d_da() + with pytest.raises(ValueError, match="dimensions"): + da.epoch.resize((4, 5)) + + +def test_resize_with_mid_coord(): + da = _make_3d_da(shape=(6, 8, 10)) + da_small = da.epoch.resize((3, 4, 5)) + assert da_small.shape == (3, 4, 5) + for dim in da_small.dims: + assert da_small[dim].size == da_small.sizes[dim] + + +def test_limit_reduces_coord_range(): + da = _make_3d_da() + x_mid = 5e-6 + da_lim = da.epoch.limit(((0.0, x_mid), (None, None), (None, None))) + assert float(da_lim["X_Grid_mid"][-1]) <= x_mid + 1e-7 + + +def test_limit_with_none_uses_existing_bounds(): + da = _make_3d_da() + da_lim = da.epoch.limit(((None, None), (None, None), (None, None))) + assert da_lim.shape == da.shape + + +def test_limit_stores_original_lims_on_coord(): + da = _make_3d_da() + x_min = float(da["X_Grid_mid"][0]) + x_max = float(da["X_Grid_mid"][-1]) + da_lim = da.epoch.limit(((0.0, 5e-6), (None, None), (None, None))) + assert da_lim["X_Grid_mid"].attrs["original_lims"] == pytest.approx( + (x_min, x_max), rel=1e-6 + ) + + +def test_limit_no_drop(): + da = _make_3d_da() + da_lim = da.epoch.limit(((0.0, 5e-6), (None, None), (None, None)), drop=False) + assert da_lim.shape == da.shape + assert np.any(np.isnan(da_lim.values)) + + +def test_animate_raises_for_4d_data(): + da = xr.DataArray( + np.zeros((3, 4, 5, 6)), + dims=["time", "X_Grid_mid", "Y_Grid_mid", "Z_Grid_mid"], + coords={ + "time": xr.Variable( + "time", [1.0, 2.0, 3.0], attrs={"long_name": "Time", "units": "s"} + ) + }, + ) + with pytest.raises(NotImplementedError, match="Voxel animations"): + da.epoch.animate() From 0aa7ecdd003657210e49345a75729e9208c315f9 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Tue, 14 Jul 2026 16:04:30 +0200 Subject: [PATCH 05/32] rollback checks in plot for time and x and y --- src/sdf_xarray/dataarray_accessor.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sdf_xarray/dataarray_accessor.py b/src/sdf_xarray/dataarray_accessor.py index aba2c66..6cf2a63 100644 --- a/src/sdf_xarray/dataarray_accessor.py +++ b/src/sdf_xarray/dataarray_accessor.py @@ -68,6 +68,8 @@ def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: Keyword arguments passed to `xarray.DataArray.plot`. """ dims = self._obj.dims + is_time_dim_present = "time" in dims + is_x_or_y_specified_in_kwargs = "x" in kwargs or "y" in kwargs if len(dims) == 1: return self._obj.plot(*args, **kwargs) @@ -78,7 +80,11 @@ def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: updated_kwargs.setdefault("y", dims[1]) return self._obj.plot(*args, **updated_kwargs) - if len(dims) == 3: + if ( + len(dims) == 3 + and not is_time_dim_present + and not is_x_or_y_specified_in_kwargs + ): return voxel_plot(self._obj, *args, **kwargs) return self._obj.plot(*args, **kwargs) From de3349be8006ad370c9392e63f493db76d9e0ea2 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Tue, 14 Jul 2026 17:15:47 +0200 Subject: [PATCH 06/32] Fix ruff linting on fixture tests --- tests/test_epoch_dataarray_accessor.py | 40 ++++++++++++++++---------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/tests/test_epoch_dataarray_accessor.py b/tests/test_epoch_dataarray_accessor.py index b76f992..6a2ee10 100644 --- a/tests/test_epoch_dataarray_accessor.py +++ b/tests/test_epoch_dataarray_accessor.py @@ -402,13 +402,15 @@ def test_shift_cmap_asymmetric_center(): assert len(result.colors) == 200 -def test_voxel_plot_returns_fig_and_ax(close_figs): +@pytest.mark.usefixtures("close_figs") +def test_voxel_plot_returns_fig_and_ax(): da = _make_3d_da() - fig, ax = sxp.voxel_plot(da) + _, ax = sxp.voxel_plot(da) assert isinstance(ax, Axes3D) -def test_voxel_plot_axis_labels(close_figs): +@pytest.mark.usefixtures("close_figs") +def test_voxel_plot_axis_labels(): da = _make_3d_da() _, ax = sxp.voxel_plot(da) assert ax.get_xlabel() == "X [m]" @@ -416,7 +418,8 @@ def test_voxel_plot_axis_labels(close_figs): assert ax.get_zlabel() == "Z [m]" -def test_voxel_plot_default_axis_limits(close_figs): +@pytest.mark.usefixtures("close_figs") +def test_voxel_plot_default_axis_limits(): da = _make_3d_da() _, ax = sxp.voxel_plot(da) xlim = ax.get_xlim() @@ -427,7 +430,8 @@ def test_voxel_plot_default_axis_limits(close_figs): assert zlim[0] < zlim[1] -def test_voxel_plot_with_xlim_ylim_zlim(close_figs): +@pytest.mark.usefixtures("close_figs") +def test_voxel_plot_with_xlim_ylim_zlim(): da = _make_3d_da() x0, x1 = 2e-6, 8e-6 y0, y1 = 2e-6, 1.8e-5 @@ -438,26 +442,30 @@ def test_voxel_plot_with_xlim_ylim_zlim(close_figs): assert ax.get_zlim() == pytest.approx((z0, z1), rel=0.1) -def test_voxel_plot_with_explicit_vmin_vmax(close_figs): +@pytest.mark.usefixtures("close_figs") +def test_voxel_plot_with_explicit_vmin_vmax(): da = _make_3d_da() - fig, ax = sxp.voxel_plot(da, vmin=0.2, vmax=0.8) + _, ax = sxp.voxel_plot(da, vmin=0.2, vmax=0.8) assert isinstance(ax, Axes3D) -def test_voxel_plot_with_vcenter(close_figs): +@pytest.mark.usefixtures("close_figs") +def test_voxel_plot_with_vcenter(): da = _make_3d_da() - fig, ax = sxp.voxel_plot(da, cmap="RdBu", vcenter=1e-2) + _, ax = sxp.voxel_plot(da, cmap="RdBu", vcenter=1e-2) assert isinstance(ax, Axes3D) -def test_voxel_plot_with_custom_mask(close_figs): +@pytest.mark.usefixtures("close_figs") +def test_voxel_plot_with_custom_mask(): da = _make_3d_da() mask = da.values > 0.5 - fig, ax = sxp.voxel_plot(da, mask=mask) + _, ax = sxp.voxel_plot(da, mask=mask) assert isinstance(ax, Axes3D) -def test_voxel_plot_aspect_auto(close_figs): +@pytest.mark.usefixtures("close_figs") +def test_voxel_plot_aspect_auto(): da = _make_3d_da() _, ax = sxp.voxel_plot(da, aspect="auto") box = ax.get_box_aspect() @@ -473,7 +481,8 @@ def test_voxel_plot_aspect_auto(close_figs): assert box[2] / box[0] == pytest.approx(z_range / x_range, rel=0.05) -def test_voxel_plot_aspect_custom_tuple(close_figs): +@pytest.mark.usefixtures("close_figs") +def test_voxel_plot_aspect_custom_tuple(): da = _make_3d_da() _, ax = sxp.voxel_plot(da, aspect=(1.0, 2.0, 3.0)) box = ax.get_box_aspect() @@ -481,14 +490,15 @@ def test_voxel_plot_aspect_custom_tuple(close_figs): assert box[2] / box[0] == pytest.approx(3.0, rel=0.01) -def test_epoch_plot_dispatches_to_voxel_for_3d_spatial_data(close_figs): +@pytest.mark.usefixtures("close_figs") +def test_epoch_plot_dispatches_to_voxel_for_3d_spatial_data(): with xr.open_dataset(TEST_FILES_DIR_3D / "0001.sdf") as ds: da = ds["Derived_Number_Density_Electron"].isel( X_Grid_mid=slice(0, 4), Y_Grid_mid=slice(0, 4), Z_Grid_mid=slice(0, 4), ) - fig, ax = da.epoch.plot() + _, ax = da.epoch.plot() assert isinstance(ax, Axes3D) assert ax.get_xlabel() == "X [m]" assert ax.get_ylabel() == "Y [m]" From d6b687a95c888dbbbd33bf29e293d13a5c312579 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Tue, 14 Jul 2026 17:30:29 +0200 Subject: [PATCH 07/32] refactor voxel axes limits and setting aspect ratio --- src/sdf_xarray/plotting.py | 88 +++++++++++++++----------------------- 1 file changed, 35 insertions(+), 53 deletions(-) diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index 9c6f755..57414f9 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -3,7 +3,7 @@ import warnings from collections.abc import Callable from dataclasses import dataclass -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Literal import numpy as np import xarray as xr @@ -11,6 +11,8 @@ if TYPE_CHECKING: import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation + from matplotlib.axes import Axes + from matplotlib.figure import Figure @dataclass @@ -172,21 +174,22 @@ def _set_axes_labels(ax: plt.Axes, axis_kwargs: dict) -> None: ax.set_ylabel(axis_kwargs["ylabel"]) -def voxel_plot( # noqa: PLR0912, PLR0915 - da, - vmin=None, - vmax=None, - vcenter=None, - mask=None, - xlim=(None, None), - ylim=(None, None), - zlim=(None, None), - aspect="equal", - elev=30, - azim=-60, - cmap="viridis", - cbar_scale=0.9, -): +def voxel_plot( + da: xr.DataArray, + vmin: float | None = None, + vmax: float | None = None, + vcenter: float | None = None, + mask: list[bool] | None = None, + xlim: tuple[float | None, float | None] = (None, None), + ylim: tuple[float | None, float | None] = (None, None), + zlim: tuple[float | None, float | None] = (None, None), + aspect: Literal["equal"] | Literal["auto"] = "equal", + elev: int = 30, + azim: int = -60, + cmap: str = "viridis", + cbar_scale: float = 0.9, + **kwargs, +) -> tuple[Figure, Axes]: """ Will take 3 dimensional data and plot it as voxels. @@ -251,40 +254,25 @@ def voxel_plot( # noqa: PLR0912, PLR0915 ax.set_ylabel(get_axis_label(da[dims[1]])) ax.set_zlabel(get_axis_label(da[dims[2]])) - # Find axis limits - xlim = list(xlim) - ylim = list(ylim) - zlim = list(zlim) - if xlim[0] is None: - xlim[0] = x.min() - if xlim[1] is None: - xlim[1] = x.max() - if ylim[0] is None: - ylim[0] = y.min() - if ylim[1] is None: - ylim[1] = y.max() - if zlim[0] is None: - zlim[0] = z.min() - if zlim[1] is None: - zlim[1] = z.max() - - # Set aspect ratio of plot + # Find and set axis limits + xlim, ylim, zlim = [ + (data.min() if low is None else low, data.max() if high is None else high) + for (low, high), data in zip([xlim, ylim, zlim], [x, y, z]) + ] + + ax.set_xlim(xlim) + ax.set_ylim(ylim) + ax.set_zlim(zlim) + + # Compute and set the box aspect ratio if aspect == "equal": - x_aspect = 1 - y_aspect = 1 - z_aspect = 1 + box_aspect = (1, 1, 1) elif aspect == "auto": - x_aspect = xlim[1] - xlim[0] - y_aspect = ylim[1] - ylim[0] - z_aspect = zlim[1] - zlim[0] + box_aspect = (xlim[1] - xlim[0], ylim[1] - ylim[0], zlim[1] - zlim[0]) else: - x_aspect, y_aspect, z_aspect = aspect - ax.set_box_aspect((x_aspect, y_aspect, z_aspect)) + box_aspect = aspect - # Limit axis of plot - ax.set_xlim(xlim[0], xlim[1]) - ax.set_ylim(ylim[0], ylim[1]) - ax.set_zlim(zlim[0], zlim[1]) + ax.set_box_aspect(box_aspect) # Colour bar and colour map if vcenter is not None: @@ -298,13 +286,7 @@ def voxel_plot( # noqa: PLR0912, PLR0915 cbar_label = get_axis_label(da) fig.colorbar(sm, ax=ax, label=cbar_label, shrink=cbar_scale, aspect=20 * cbar_scale) - ax.voxels( - x_mesh, - y_mesh, - z_mesh, - mask, - facecolors=colours, - ) + ax.voxels(x_mesh, y_mesh, z_mesh, mask, facecolors=colours, **kwargs) return fig, ax From 7cef173439c4b263a431f6e5bec3579de8769103 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Tue, 14 Jul 2026 17:39:00 +0200 Subject: [PATCH 08/32] Improve docstring and types --- src/sdf_xarray/plotting.py | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index 57414f9..d029d1c 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -12,6 +12,7 @@ import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation from matplotlib.axes import Axes + from matplotlib.colors import ListedColormap from matplotlib.figure import Figure @@ -58,12 +59,13 @@ def get_frame_title( return f"{title_custom}{title_t_axis}{title_sdf}" -def get_axis_label(dim: xr.DataArray): +def get_axis_label(dim: xr.DataArray) -> str: + """Formats the axes label for a given dim in the form of ``dim.long_name [dim.units]``.""" return f"{dim.long_name} [{dim.units}]" -def _recover_vertex_coord(w_mid): - # Takes a midpoint coordinate, returns a vertex coordinate +def _recover_vertex_coord(w_mid: xr.DataArray) -> np.ndarray: + """Takes a midpoint coordinate, returns a vertex coordinate.""" w_size = w_mid.size dw = w_mid[1] - w_mid[0] w = np.zeros(w_mid.size + 1) @@ -72,10 +74,30 @@ def _recover_vertex_coord(w_mid): return w -def shift_cmap(cmap, vmin, vmax, vcenter, N=1024): +def shift_cmap( + cmap: str, vmin: float, vmax: float, vcenter: float, N: int = 1024 +) -> ListedColormap: """ - Creates a new colourmap where the visual center of the original - colourmap is shifted to a specific data value. + Create a new colormap where the visual center of the original + colormap is shifted to a specific data value. + + Parameters + ---------- + cmap : str or matplotlib.colors.Colormap + The name of the original colormap (e.g., 'viridis') or the colormap object itself. + vmin : float + The minimum value of your data range. + vmax : float + The maximum value of your data range. + vcenter : float + The data value that should map to the visual midpoint (0.5) of the colormap. + N : int, default 1024 + The number of interpolation steps (color bins) in the new colormap. + + Returns + ------- + matplotlib.colors.ListedColormap + The newly constructed, shifted colormap. """ import matplotlib.colors as mc # noqa: PLC0415 import matplotlib.pyplot as plt # noqa: PLC0415 From 93c8b9e909cc7812322e87e8ad2e7da3958e7fca Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Wed, 15 Jul 2026 12:36:46 +0200 Subject: [PATCH 09/32] change voxel plot warning to use `warnings.warn()` --- src/sdf_xarray/plotting.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index d029d1c..1f97a02 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -242,7 +242,10 @@ def voxel_plot( """ import matplotlib.pyplot as plt # noqa: PLC0415 - print("Warning! voxel plots can be extremely intensive!") + warnings.warn( + "Voxel plots can be extremely computationally expensive and may take longer than expected to plot.", + stacklevel=2, + ) # Limit arrays based on axis limits da = da.epoch.limit((xlim, ylim, zlim)) From 292e4752976da062c6699a8534c937340acc0b78 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Wed, 15 Jul 2026 13:57:55 +0200 Subject: [PATCH 10/32] update dataarray plot accessor to remove x or y check --- src/sdf_xarray/dataarray_accessor.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/sdf_xarray/dataarray_accessor.py b/src/sdf_xarray/dataarray_accessor.py index 6cf2a63..d62c250 100644 --- a/src/sdf_xarray/dataarray_accessor.py +++ b/src/sdf_xarray/dataarray_accessor.py @@ -69,7 +69,6 @@ def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: """ dims = self._obj.dims is_time_dim_present = "time" in dims - is_x_or_y_specified_in_kwargs = "x" in kwargs or "y" in kwargs if len(dims) == 1: return self._obj.plot(*args, **kwargs) @@ -80,11 +79,7 @@ def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: updated_kwargs.setdefault("y", dims[1]) return self._obj.plot(*args, **updated_kwargs) - if ( - len(dims) == 3 - and not is_time_dim_present - and not is_x_or_y_specified_in_kwargs - ): + if len(dims) == 3 and not is_time_dim_present: return voxel_plot(self._obj, *args, **kwargs) return self._obj.plot(*args, **kwargs) From cc6fd44f5fc28c0824e67a732e1f851688998740 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Thu, 16 Jul 2026 11:38:02 +0200 Subject: [PATCH 11/32] Add global pytest filter for `userWarning` to ignore voxel plotting warning --- pyproject.toml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 039d3c9..94ab729 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -136,5 +136,7 @@ ignore = [ "B9", # flake8-bugbear opinionated warnings "PLR0913", # remove maximum number of arguments in a function ] -exclude = ["**/_version.py"] -# Auto-generated file +exclude = ["**/_version.py"] # Auto-generated file + +[tool.pytest.ini_options] +filterwarnings = ['ignore::UserWarning'] From 763f0420f0f6423c69155e89d7880e4243aa79aa Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Fri, 17 Jul 2026 11:48:11 +0200 Subject: [PATCH 12/32] Update voxel_plot to accept user axes --- src/sdf_xarray/plotting.py | 12 +++++++++--- tests/test_epoch_dataarray_accessor.py | 8 ++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index 1f97a02..f643676 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -198,6 +198,7 @@ def _set_axes_labels(ax: plt.Axes, axis_kwargs: dict) -> None: def voxel_plot( da: xr.DataArray, + ax: plt.Axes | None = None, vmin: float | None = None, vmax: float | None = None, vcenter: float | None = None, @@ -211,7 +212,7 @@ def voxel_plot( cmap: str = "viridis", cbar_scale: float = 0.9, **kwargs, -) -> tuple[Figure, Axes]: +) -> None: """ Will take 3 dimensional data and plot it as voxels. @@ -219,6 +220,8 @@ def voxel_plot( ---------- da DataArray to be plotted. + ax + Matplotlib axes on which to plot. vmin Minimum value. If `mask` is not stated, will be used to define the mask. vmax @@ -247,6 +250,11 @@ def voxel_plot( stacklevel=2, ) + if ax is None: + fig, ax = plt.subplots(figsize=(8, 6), subplot_kw={"projection": "3d"}) + else: + fig = ax.get_figure() + # Limit arrays based on axis limits da = da.epoch.limit((xlim, ylim, zlim)) @@ -270,8 +278,6 @@ def voxel_plot( mask = (da > vmin) * (da < vmax) # Plot the data array - fig = plt.figure(figsize=(8, 6)) - ax = fig.add_subplot(projection="3d") ax.view_init(elev, azim) # Set axis labels diff --git a/tests/test_epoch_dataarray_accessor.py b/tests/test_epoch_dataarray_accessor.py index 6a2ee10..667366f 100644 --- a/tests/test_epoch_dataarray_accessor.py +++ b/tests/test_epoch_dataarray_accessor.py @@ -409,6 +409,14 @@ def test_voxel_plot_returns_fig_and_ax(): assert isinstance(ax, Axes3D) +@pytest.mark.usefixtures("close_figs") +def test_voxel_plot_accepts_axes(): + da = _make_3d_da() + _, ax = plt.subplots(figsize=(8, 6), subplot_kw={"projection": "3d"}) + sxp.voxel_plot(da, ax=ax) + assert isinstance(ax, Axes3D) + + @pytest.mark.usefixtures("close_figs") def test_voxel_plot_axis_labels(): da = _make_3d_da() From 822277552a78efb09cc2da1095e7bb2290f069be Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Fri, 17 Jul 2026 11:50:54 +0200 Subject: [PATCH 13/32] Remove unused matplotlib imports --- src/sdf_xarray/plotting.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index f643676..29ba7fc 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -11,9 +11,7 @@ if TYPE_CHECKING: import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation - from matplotlib.axes import Axes from matplotlib.colors import ListedColormap - from matplotlib.figure import Figure @dataclass From 113430532db9558cdc8ce07d94cee7da9b2e8331 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Fri, 17 Jul 2026 12:24:20 +0200 Subject: [PATCH 14/32] Fix voxel_plot return type --- src/sdf_xarray/plotting.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index 29ba7fc..6522851 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -210,7 +210,7 @@ def voxel_plot( cmap: str = "viridis", cbar_scale: float = 0.9, **kwargs, -) -> None: +) -> tuple[plt.Figure, plt.Axes]: """ Will take 3 dimensional data and plot it as voxels. @@ -219,7 +219,7 @@ def voxel_plot( da DataArray to be plotted. ax - Matplotlib axes on which to plot. + Matplotlib axes on which to plot (This must use a 3d projection). vmin Minimum value. If `mask` is not stated, will be used to define the mask. vmax From 90dcacc55c7c38febe96bc37d49dd7bd73e7585f Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Fri, 17 Jul 2026 12:26:30 +0200 Subject: [PATCH 15/32] Make default mask inclusive of vmin and vmax --- src/sdf_xarray/plotting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index 6522851..ea42088 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -273,7 +273,7 @@ def voxel_plot( # Mask out data if mask is None: - mask = (da > vmin) * (da < vmax) + mask = (da >= vmin) * (da <= vmax) # Plot the data array ax.view_init(elev, azim) From fed1a5e7e548612b12788242ef9912374e4b6530 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Fri, 17 Jul 2026 12:30:56 +0200 Subject: [PATCH 16/32] Fix type hinting in voxel_plot --- src/sdf_xarray/plotting.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index ea42088..a384e8e 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -200,13 +200,13 @@ def voxel_plot( vmin: float | None = None, vmax: float | None = None, vcenter: float | None = None, - mask: list[bool] | None = None, + mask: np.ndarray[bool] | None = None, xlim: tuple[float | None, float | None] = (None, None), ylim: tuple[float | None, float | None] = (None, None), zlim: tuple[float | None, float | None] = (None, None), - aspect: Literal["equal"] | Literal["auto"] = "equal", - elev: int = 30, - azim: int = -60, + aspect: Literal["equal", "auto"] | tuple[float, float, float] = "equal", + elev: float = 30, + azim: float = -60, cmap: str = "viridis", cbar_scale: float = 0.9, **kwargs, From a8bfaf3ebc342cc0a8e5e4508aa18637e3058741 Mon Sep 17 00:00:00 2001 From: ShaunD137 Date: Tue, 21 Jul 2026 09:30:11 +0100 Subject: [PATCH 17/32] remove time check in plot accessor --- src/sdf_xarray/dataarray_accessor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sdf_xarray/dataarray_accessor.py b/src/sdf_xarray/dataarray_accessor.py index d62c250..aba2c66 100644 --- a/src/sdf_xarray/dataarray_accessor.py +++ b/src/sdf_xarray/dataarray_accessor.py @@ -68,7 +68,6 @@ def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: Keyword arguments passed to `xarray.DataArray.plot`. """ dims = self._obj.dims - is_time_dim_present = "time" in dims if len(dims) == 1: return self._obj.plot(*args, **kwargs) @@ -79,7 +78,7 @@ def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: updated_kwargs.setdefault("y", dims[1]) return self._obj.plot(*args, **updated_kwargs) - if len(dims) == 3 and not is_time_dim_present: + if len(dims) == 3: return voxel_plot(self._obj, *args, **kwargs) return self._obj.plot(*args, **kwargs) From 0f1adf5a097be0b0d4fd17b09606b095cccae2fa Mon Sep 17 00:00:00 2001 From: ShaunD137 Date: Wed, 22 Jul 2026 14:17:26 +0100 Subject: [PATCH 18/32] add optional histogram plot to plot accessor --- src/sdf_xarray/dataarray_accessor.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sdf_xarray/dataarray_accessor.py b/src/sdf_xarray/dataarray_accessor.py index aba2c66..c330573 100644 --- a/src/sdf_xarray/dataarray_accessor.py +++ b/src/sdf_xarray/dataarray_accessor.py @@ -50,7 +50,7 @@ class EpochAccessor: def __init__(self, xarray_obj: xr.DataArray): self._obj = xarray_obj - def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: + def plot(self, hist = False, *args, **kwargs) -> DataArrayPlotAccessor: """ Builds upon `xarray.DataArray.plot` while changing some of its default behaviours. @@ -62,6 +62,8 @@ def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: Parameters ---------- + hist + If `True`, will plot a histogram regardless of dimensionality (default = False). args Positional arguments passed to `xarray.DataArray.plot`. kwargs @@ -69,6 +71,9 @@ def plot(self, *args, **kwargs) -> DataArrayPlotAccessor: """ dims = self._obj.dims + if hist == True: + return self._obj.plot.hist(*args, **kwargs) + if len(dims) == 1: return self._obj.plot(*args, **kwargs) From e83b51d9aadb75985499d430a535ac7254d75802 Mon Sep 17 00:00:00 2001 From: ShaunD137 Date: Wed, 22 Jul 2026 14:46:08 +0100 Subject: [PATCH 19/32] remove now unnecessary tests --- tests/test_epoch_dataarray_accessor.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/tests/test_epoch_dataarray_accessor.py b/tests/test_epoch_dataarray_accessor.py index 667366f..50338d7 100644 --- a/tests/test_epoch_dataarray_accessor.py +++ b/tests/test_epoch_dataarray_accessor.py @@ -323,22 +323,6 @@ def test_epoch_plot_flips_axis_order_for_2d_data_with_additional_params(subplots assert ax.get_ylim() == pytest.approx((0.0, 0.5), abs=1e-2) -def test_epoch_plot_flips_axis_order_for_2d_data_but_not_when_time_dim_present( - subplots, -): - with xr.open_mfdataset( - TEST_FILES_DIR_2D_MW.glob("*.sdf"), - preprocess=SDFPreprocess(), - combine="nested", - compat="no_conflicts", - join="outer", - ) as ds: - _, ax = subplots - plot = ds["Derived_Number_Density_electron"].epoch.plot(ax=ax) - - assert type(plot[2]) is BarContainer - - def _make_3d_da(shape=(4, 5, 6)): """Small synthetic 3-D DataArray with the metadata voxel_plot expects.""" nx, ny, nz = shape From 43f4e97a66e9827d1e26b0d79f9675c227ae9e9e Mon Sep 17 00:00:00 2001 From: ShaunD137 Date: Wed, 22 Jul 2026 14:46:40 +0100 Subject: [PATCH 20/32] documentation update --- docs/animation.md | 11 +++- docs/figures/voxel_plot_high_res.png | Bin 0 -> 212132 bytes docs/index.md | 1 + docs/plots.md | 91 +++++++++++++++++++++++++++ docs/understanding_datasets.md | 65 ++++++++++++++----- 5 files changed, 149 insertions(+), 19 deletions(-) create mode 100644 docs/figures/voxel_plot_high_res.png create mode 100644 docs/plots.md diff --git a/docs/animation.md b/docs/animation.md index c512b4a..9e84580 100644 --- a/docs/animation.md +++ b/docs/animation.md @@ -35,9 +35,10 @@ resolved data has 2 dimensions. | Dimensions | Plotting function | Notes | | ---------- | ----------------------------- | --------------------- | -| `2` | | | -| `3` | | | -| `>3` | | Not fully implemented | +| 2 | | | +| 3 | | | +| 4 | | WIP | +| >4 | | Not fully implemented | ### 1D simulation @@ -103,6 +104,10 @@ anim.show() ### 3D simulation +```{warning} +[Voxel](./plots.md#voxel-plots) animations are not currently implemented. +``` + Opening a 3D simulation as a multi-file dataset and plotting it will return a . However, this may not be desirable. We can plot a 3D simulation along a certain plane in the diff --git a/docs/figures/voxel_plot_high_res.png b/docs/figures/voxel_plot_high_res.png new file mode 100644 index 0000000000000000000000000000000000000000..0e2262b3717b76829ca46bcf8b39b0ca34ef2347 GIT binary patch literal 212132 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

~|6M!rW^kfZ>)!u$;O$YKb$F_A#B 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 CL5Y+A literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md index 336ce52..8e21c71 100644 --- a/docs/index.md +++ b/docs/index.md @@ -21,6 +21,7 @@ why_sdf_xarray.md loading_data.md understanding_datasets.md unit_conversion.md +plots.md animation.md ``` diff --git a/docs/plots.md b/docs/plots.md new file mode 100644 index 0000000..56f7629 --- /dev/null +++ b/docs/plots.md @@ -0,0 +1,91 @@ +--- +file_format: mystnb +kernelspec: + name: python3 +--- + +# Plots + +You can plot datasets using +[`xarray.DataArray.epoch.plot`](project:#sdf_xarray.dataarray_accessor.EpochAccessor.plot). +This is a custom plotting routine that builds on top of +, so you keep the familiar plotting +behaviour while using conveniences (see +[here](project:#sdf_xarray.dataarray_accessor.EpochAccessor.plot) for details). +Under the hood, plotting is still handled by , which means you +can use the full API to customise your figure. + +| Dimensions | Base plotting function | Notes | +| ---------- | ----------------------------- | --------------------- | +| 1 | | | +| 2 | | | +| 3 | | Custom functionality built for | +| >3 | | Not fully implemented | + +## Line plots + +One dimensional data will be plotted as a line. Multiple lines can be easily +plotted at the same time. + +```{code-cell} ipython3 +import sdf_xarray as sdfxr +import matplotlib.pyplot as plt +ds = sdfxr.open_dataset("tutorial_dataset_1d/0010.sdf") +da_1 = ds["Derived_Number_Density_Electron"] +da_2 = ds["Derived_Number_Density_Ion"] +da_1.epoch.plot(label = "Electron") +da_2.epoch.plot(label = "Ion") +plt.legend() +plt.show() +``` + +## Mesh plots + +Two dimensional data will be plotted as a mesh. + +```{code-cell} ipython3 +ds = sdfxr.open_dataset("tutorial_dataset_2d/0010.sdf") +da = ds["Derived_Number_Density_Electron"] +da.epoch.plot() +``` + +## Voxel plots + +Three dimensional data will be plotted using voxels. This behaviour is not native +to , it has been custom built specifically for this package. + +```bash +ds = sdfxr.open_dataset("tutorial_dataset_3d/0000.sdf") +da = ds["Derived_Number_Density"] +da.epoch.plot(vmin = 1e27) +``` + +![voxel_plot_high_res](./figures/voxel_plot_high_res.png) + +```{warning} +Voxel plots can be extremely computationally expensive and may take longer than +expected to plot. +``` + +Because voxel plots are very expensive, even with relatively small data arrays, +plotting can be sped up by using , +which uses interpolation to reduce the resolution. + +```{code-cell} ipython3 +ds = sdfxr.open_dataset("tutorial_dataset_3d/0005.sdf") +da = ds["Derived_Number_Density"] +da_resized = da.epoch.resize((20, 20, 20)) +da_resized.epoch.plot(vmin = 1e27) +``` + +## Histograms + +When the data array has four or more dimensions (or is specified by the user), it will +be plotted as a histogram. + +```{code-cell} ipython3 +ds = sdfxr.open_dataset("tutorial_dataset_3d/0005.sdf") +da = ds["Derived_Number_Density"] + +da.epoch.plot(hist = True) +``` \ No newline at end of file diff --git a/docs/understanding_datasets.md b/docs/understanding_datasets.md index d2c1914..c0d9956 100644 --- a/docs/understanding_datasets.md +++ b/docs/understanding_datasets.md @@ -29,23 +29,10 @@ ds = sdfxr.open_mfdataset("tutorial_dataset_1d/*.sdf") ds["Electric_Field_Ex"] ``` -## Plotting +## Visulisation -You can plot datasets using -[`xarray.DataArray.epoch.plot`](project:#sdf_xarray.dataarray_accessor.EpochAccessor.plot). -This is a custom plotting routine that builds on top of -, so you keep the familiar plotting -behaviour while using conveniences (see -[here](project:#sdf_xarray.dataarray_accessor.EpochAccessor.plot) for details). -Under the hood, plotting is still handled by , which means you -can use the full API to customise your figure. - -```{code-cell} ipython3 -# This is discretized in both space and time -ds["Electric_Field_Ex"].epoch.plot() -plt.title("Electric field along the x-axis") -plt.show() -``` +`sdf-xarray` has built-in plotting and animation functionality, more details can +be found on [Plots](./plots.md) and [Animations](./animation.md). ## Dimension slicing @@ -56,6 +43,7 @@ for easy indexing. To quickly determine the number of time steps available, you can check the size of the time dimension. ```{code-cell} ipython3 +ds = sdfxr.open_mfdataset("tutorial_dataset_1d/*.sdf") # This corresponds to the number of individual SDF files loaded print(f"There are a total of {ds['time'].size} time steps") @@ -122,6 +110,51 @@ print(f"Total particle energy absorbed: {ds["Total_Particle_Energy_in_Simulation print(f"The laser absorption fraction: {ds["Laser_Absorption_Fraction_in_Simulation"][-1].values:.1f} %") ``` +## Limit + +The `.epoch` accessor, has the ability to "limit" data arrays. This is a helper +function which applies to the upper and lower bounds +of each dimension. You can use `None` to preserve the existing limit. + +```{code-cell} ipython3 +ds = sdfxr.open_dataset("tutorial_dataset_2d/0020.sdf") +da = ds["Derived_Number_Density_Electron"] +da.epoch.plot() +print(f"Orignal shape: {da.shape}") +plt.show() +``` + +```{code-cell} ipython3 +da_limit = da.epoch.limit(((-2e-6, 2e-6), (None, 0))) +da_limit.epoch.plot() +print(f"New shape: {da_limit.shape}") +plt.show() +``` + +## Resize + +The data arrays can be interpolated with +to either increase or decrease the resolution while mantaining the general structure. +Decreasing the size may be useful to download large data from HPCs to local machines +or ploting with [voxel plots](./plots.md#voxel-plots). Be aware that the original +data will not be preserved. + +```{code-cell} ipython3 +ds = sdfxr.open_dataset("tutorial_dataset_2d/0020.sdf") +da = ds["Derived_Number_Density_Electron"] + +da.epoch.plot() +print(f"Orignal shape: {da.shape}") +plt.show() +``` + +```{code-cell} ipython3 +da_resized = da.epoch.resize((50, 50)) +da_resized.epoch.plot() +print(f"New shape: {da_resized.shape}") +plt.show() +``` + ## Visualisation on HPC Machines In many cases you will be running EPOCH simulations via a HPC cluster and your From 5be1c6300c2ef9e714b1dd835c90c47063012dcd Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Thu, 23 Jul 2026 10:17:18 +0200 Subject: [PATCH 21/32] Fix linting --- src/sdf_xarray/dataarray_accessor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sdf_xarray/dataarray_accessor.py b/src/sdf_xarray/dataarray_accessor.py index c330573..7b7f790 100644 --- a/src/sdf_xarray/dataarray_accessor.py +++ b/src/sdf_xarray/dataarray_accessor.py @@ -50,7 +50,7 @@ class EpochAccessor: def __init__(self, xarray_obj: xr.DataArray): self._obj = xarray_obj - def plot(self, hist = False, *args, **kwargs) -> DataArrayPlotAccessor: + def plot(self, hist=False, *args, **kwargs) -> DataArrayPlotAccessor: """ Builds upon `xarray.DataArray.plot` while changing some of its default behaviours. @@ -71,7 +71,7 @@ def plot(self, hist = False, *args, **kwargs) -> DataArrayPlotAccessor: """ dims = self._obj.dims - if hist == True: + if hist: return self._obj.plot.hist(*args, **kwargs) if len(dims) == 1: From f7ebfce28ad3d1db668ae6f20c13d2473aa993aa Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Thu, 23 Jul 2026 10:17:37 +0200 Subject: [PATCH 22/32] Remove unusued import from tests --- tests/test_epoch_dataarray_accessor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_epoch_dataarray_accessor.py b/tests/test_epoch_dataarray_accessor.py index 50338d7..b889023 100644 --- a/tests/test_epoch_dataarray_accessor.py +++ b/tests/test_epoch_dataarray_accessor.py @@ -8,7 +8,6 @@ import xarray as xr from matplotlib.animation import PillowWriter from matplotlib.colors import ListedColormap -from matplotlib.container import BarContainer from mpl_toolkits.mplot3d import Axes3D from packaging.version import Version From f812213c4e21ed93f17ec8699a781391d7b79cba Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Thu, 23 Jul 2026 10:19:36 +0200 Subject: [PATCH 23/32] Fix backticks in plotting docstring --- src/sdf_xarray/dataarray_accessor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdf_xarray/dataarray_accessor.py b/src/sdf_xarray/dataarray_accessor.py index 7b7f790..819d8ba 100644 --- a/src/sdf_xarray/dataarray_accessor.py +++ b/src/sdf_xarray/dataarray_accessor.py @@ -63,7 +63,7 @@ def plot(self, hist=False, *args, **kwargs) -> DataArrayPlotAccessor: Parameters ---------- hist - If `True`, will plot a histogram regardless of dimensionality (default = False). + If ``True``, will plot a histogram regardless of dimensionality (default = ``False``). args Positional arguments passed to `xarray.DataArray.plot`. kwargs From ba158750cd88c352806ae1f22b8620e4baf7ceb1 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Thu, 23 Jul 2026 10:37:48 +0200 Subject: [PATCH 24/32] rename docs plots to plotting --- docs/index.md | 2 +- docs/{plots.md => plotting.md} | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) rename docs/{plots.md => plotting.md} (97%) diff --git a/docs/index.md b/docs/index.md index 8e21c71..8cdfb2b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -21,7 +21,7 @@ why_sdf_xarray.md loading_data.md understanding_datasets.md unit_conversion.md -plots.md +plotting.md animation.md ``` diff --git a/docs/plots.md b/docs/plotting.md similarity index 97% rename from docs/plots.md rename to docs/plotting.md index 56f7629..847af17 100644 --- a/docs/plots.md +++ b/docs/plotting.md @@ -4,7 +4,7 @@ kernelspec: name: python3 --- -# Plots +# Plotting You can plot datasets using [`xarray.DataArray.epoch.plot`](project:#sdf_xarray.dataarray_accessor.EpochAccessor.plot). @@ -47,6 +47,7 @@ Two dimensional data will be plotted as a mesh. ds = sdfxr.open_dataset("tutorial_dataset_2d/0010.sdf") da = ds["Derived_Number_Density_Electron"] da.epoch.plot() +plt.show() ``` ## Voxel plots @@ -54,10 +55,11 @@ da.epoch.plot() Three dimensional data will be plotted using voxels. This behaviour is not native to , it has been custom built specifically for this package. -```bash +```python ds = sdfxr.open_dataset("tutorial_dataset_3d/0000.sdf") da = ds["Derived_Number_Density"] da.epoch.plot(vmin = 1e27) +plt.show() ``` ![voxel_plot_high_res](./figures/voxel_plot_high_res.png) @@ -76,6 +78,7 @@ ds = sdfxr.open_dataset("tutorial_dataset_3d/0005.sdf") da = ds["Derived_Number_Density"] da_resized = da.epoch.resize((20, 20, 20)) da_resized.epoch.plot(vmin = 1e27) +plt.show() ``` ## Histograms @@ -88,4 +91,5 @@ ds = sdfxr.open_dataset("tutorial_dataset_3d/0005.sdf") da = ds["Derived_Number_Density"] da.epoch.plot(hist = True) +plt.show() ``` \ No newline at end of file From cc77c4ce74ebffcc5d877b7eab76b61cdb88ad1f Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Thu, 23 Jul 2026 10:38:09 +0200 Subject: [PATCH 25/32] Fix plotting link in why_sdf_xarray --- docs/why_sdf_xarray.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/why_sdf_xarray.md b/docs/why_sdf_xarray.md index 76bf3f9..58cecfb 100644 --- a/docs/why_sdf_xarray.md +++ b/docs/why_sdf_xarray.md @@ -7,7 +7,7 @@ There are several benefits to using this package over the [`sdf_helper`](https:/ - [data to numpy and pandas](https://docs.xarray.dev/en/stable/user-guide/pandas.html) - Data can be easily converted to [numpy](https://www.numpy.org/) or [pandas](https://pandas.pydata.org/) if you prefer to work with raw data. - [data labelling](project:understanding_datasets.md) - All SDF files come with a bunch of information about them such as the `dimensions`, `units` and `name` of the variable. In these are added to each variable making it much easier to read. - [lazy/partial loading](https://docs.xarray.dev/en/stable/internals/internal-design.html#lazy-loading) - This reduces the RAM requirements when loading large SDF files as we only load the actual array values when they are needed. -- [plotting](project:understanding_datasets.md#plotting) - You can easily plot variables across several dimensions including time using built in support. +- [plotting](project:plotting.md) - You can easily plot variables across several dimensions including time using built in support. - [animating](project:animation.md) - Visualise your data across time or slice through another dimension and make beautiful GIFs for your presentations. - [deck loading](loading-input-deck) - automatically loads in the associated `input.deck` utilised when creating the simulation so that you can access setup variables. - [easier unit conversion](project:unit_conversion.md) - Convert dimensions and variable units to other types with the help of [`pint`](https://pint.readthedocs.io/en/stable). From 158f04d502f6f4d36982744f569bb06c61cbe397 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Thu, 23 Jul 2026 10:38:15 +0200 Subject: [PATCH 26/32] Fix spelling mistakes --- docs/understanding_datasets.md | 6 +++--- src/sdf_xarray/plotting.py | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/understanding_datasets.md b/docs/understanding_datasets.md index c0d9956..fde4828 100644 --- a/docs/understanding_datasets.md +++ b/docs/understanding_datasets.md @@ -29,7 +29,7 @@ ds = sdfxr.open_mfdataset("tutorial_dataset_1d/*.sdf") ds["Electric_Field_Ex"] ``` -## Visulisation +## Visualisation `sdf-xarray` has built-in plotting and animation functionality, more details can be found on [Plots](./plots.md) and [Animations](./animation.md). @@ -54,7 +54,7 @@ print(f"The time at the 20th simulation step is {sim_time:.2e} s") You can select and extract a single simulation snapshot using the integer index of the time step with the function. This can be -done by passsing the index to the `time` parameter (e.g., `time=0` for +done by passing the index to the `time` parameter (e.g., `time=0` for the first snapshot). ```{code-cell} ipython3 @@ -62,7 +62,7 @@ ds["Electric_Field_Ex"].isel(time=20) ``` We can also use the function if you wish to pass a -value intead of an index. +value instead of an index. ```{tip} If you know roughly what time you wish to select but not the exact value diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index a384e8e..79674f9 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -52,7 +52,7 @@ def get_frame_title( t_axis_units_formatted = f" [{t_axis_units}]" if t_axis_units else "" title_t_axis = f"{data[t].long_name} = {t_axis_value:.2e}{t_axis_units_formatted}" - # Adds sdf name to the title, if specifed + # Adds sdf name to the title, if specified title_sdf = f", {frame:04d}.sdf" if display_sdf_name else "" return f"{title_custom}{title_t_axis}{title_sdf}" @@ -122,7 +122,7 @@ def calculate_window_boundaries( t: str = "time", ) -> np.ndarray: """Calculate the boundaries a moving window frame. If the user specifies xlim, this will - be used as the initial boundaries and the window will move along acordingly. + be used as the initial boundaries and the window will move along accordingly. Parameters ---------- @@ -153,7 +153,7 @@ def calculate_window_boundaries( window_boundaries[i, 0] = x_grid_non_nan[0] - x_half_cell window_boundaries[i, 1] = x_grid_non_nan[-1] + x_half_cell - # User's choice for initial window edge supercedes the one calculated + # User's choice for initial window edge supersedes the one calculated if xlim is not None: window_boundaries = window_boundaries + xlim - window_boundaries[0] return window_boundaries @@ -225,9 +225,9 @@ def voxel_plot( vmax Maximum value. If `mask` is not stated, will be used to define the mask. vcenter - Center value of the colourmap. Useful for diverging colourmaps with non-symetrical data. + Center value of the colourmap. Useful for diverging colourmaps with non-symmetrical data. mask - Array of bools specifing which cells to show. Must be same size as `da` + Array of bools specifying which cells to show. Must be same size as ``da`` xlim, ylim, zlim Sets the limits of the plot. aspect @@ -235,7 +235,7 @@ def voxel_plot( elev Elevation angle in degrees. (default = 30) azim - Azimithul angle in degrees. (default = -60) + Azimuthal angle in degrees. (default = -60) cmap Colourmap (default = "viridis") cbar_scale From c9df175ebc5fafdabd26656f2e7f8ff66a01f87d Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Mon, 27 Jul 2026 11:16:16 +0100 Subject: [PATCH 27/32] Change name of resize accessor link in docs --- docs/plotting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plotting.md b/docs/plotting.md index 847af17..80f76c5 100644 --- a/docs/plotting.md +++ b/docs/plotting.md @@ -70,7 +70,7 @@ expected to plot. ``` Because voxel plots are very expensive, even with relatively small data arrays, -plotting can be sped up by using , +plotting can be sped up by using [`xarray.DataArray.epoch.resize`](project:#sdf_xarray.dataarray_accessor.EpochAccessor.resize), which uses interpolation to reduce the resolution. ```{code-cell} ipython3 From 1621bbdc9a830eb422c0bc65b0c37851e8d3b793 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Mon, 27 Jul 2026 11:26:53 +0100 Subject: [PATCH 28/32] Fix new ruff rules --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 94ab729..158f2c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -135,6 +135,8 @@ ignore = [ "PLR2004", # magic-comparison "B9", # flake8-bugbear opinionated warnings "PLR0913", # remove maximum number of arguments in a function + "PLR0917", # remove maximum number of positional arguments in a function + "BLE001", # allow capturing of base exception ] exclude = ["**/_version.py"] # Auto-generated file From ed2593c6ea54e3bc1704336b616a1a6c23834f09 Mon Sep 17 00:00:00 2001 From: Joel Adams <57064123+JoelLucaAdams@users.noreply.github.com> Date: Tue, 28 Jul 2026 10:11:40 +0100 Subject: [PATCH 29/32] Apply suggestions from code review Co-authored-by: Liam Pattinson --- docs/understanding_datasets.md | 2 +- src/sdf_xarray/dataarray_accessor.py | 2 +- src/sdf_xarray/plotting.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/understanding_datasets.md b/docs/understanding_datasets.md index fde4828..480452f 100644 --- a/docs/understanding_datasets.md +++ b/docs/understanding_datasets.md @@ -112,7 +112,7 @@ print(f"The laser absorption fraction: {ds["Laser_Absorption_Fraction_in_Simulat ## Limit -The `.epoch` accessor, has the ability to "limit" data arrays. This is a helper +The `.epoch` accessor has the ability to "limit" data arrays. This is a helper function which applies to the upper and lower bounds of each dimension. You can use `None` to preserve the existing limit. diff --git a/src/sdf_xarray/dataarray_accessor.py b/src/sdf_xarray/dataarray_accessor.py index 819d8ba..f9bf69c 100644 --- a/src/sdf_xarray/dataarray_accessor.py +++ b/src/sdf_xarray/dataarray_accessor.py @@ -144,7 +144,7 @@ def resize( for i in range(len(da_resized.dims)): coord = list(da_resized.dims)[i] - if coord[-4:] == "_mid": + if coord.endswith("_mid"): # If the coordinate is a midpoint coordinate, care must be taken to resize correctly vertex_coord = _recover_vertex_coord(da[coord]) vertex_coord_resized = np.linspace( diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index 79674f9..cf9dbc4 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -212,7 +212,7 @@ def voxel_plot( **kwargs, ) -> tuple[plt.Figure, plt.Axes]: """ - Will take 3 dimensional data and plot it as voxels. + Plot 3-dimensional data as voxels. Parameters ---------- From 357d55c683ad6fea6302cbcf4d9579c5bf487353 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Tue, 28 Jul 2026 10:21:28 +0100 Subject: [PATCH 30/32] Fix broken internal plotting links in docs --- docs/animation.md | 2 +- docs/understanding_datasets.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/animation.md b/docs/animation.md index 9e84580..49cd723 100644 --- a/docs/animation.md +++ b/docs/animation.md @@ -105,7 +105,7 @@ anim.show() ### 3D simulation ```{warning} -[Voxel](./plots.md#voxel-plots) animations are not currently implemented. +[Voxel](./plotting.md#voxel-plots) animations are not currently implemented. ``` Opening a 3D simulation as a multi-file dataset and plotting it will diff --git a/docs/understanding_datasets.md b/docs/understanding_datasets.md index 480452f..087731b 100644 --- a/docs/understanding_datasets.md +++ b/docs/understanding_datasets.md @@ -32,7 +32,7 @@ ds["Electric_Field_Ex"] ## Visualisation `sdf-xarray` has built-in plotting and animation functionality, more details can -be found on [Plots](./plots.md) and [Animations](./animation.md). +be found on [](./plotting.md) and [](./animation.md). ## Dimension slicing @@ -136,7 +136,7 @@ plt.show() The data arrays can be interpolated with to either increase or decrease the resolution while mantaining the general structure. Decreasing the size may be useful to download large data from HPCs to local machines -or ploting with [voxel plots](./plots.md#voxel-plots). Be aware that the original +or ploting with [](./plotting.md#voxel-plots). Be aware that the original data will not be preserved. ```{code-cell} ipython3 From aec2cc96c58d5fa1d0a2dbb09b75bbd86f8bbbe3 Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Tue, 28 Jul 2026 10:21:40 +0100 Subject: [PATCH 31/32] Remove types from `shift_cmap` docstring --- src/sdf_xarray/plotting.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/sdf_xarray/plotting.py b/src/sdf_xarray/plotting.py index cf9dbc4..72a582c 100644 --- a/src/sdf_xarray/plotting.py +++ b/src/sdf_xarray/plotting.py @@ -81,20 +81,19 @@ def shift_cmap( Parameters ---------- - cmap : str or matplotlib.colors.Colormap + cmap The name of the original colormap (e.g., 'viridis') or the colormap object itself. - vmin : float + vmin The minimum value of your data range. - vmax : float + vmax The maximum value of your data range. - vcenter : float + vcenter The data value that should map to the visual midpoint (0.5) of the colormap. - N : int, default 1024 + N The number of interpolation steps (color bins) in the new colormap. Returns ------- - matplotlib.colors.ListedColormap The newly constructed, shifted colormap. """ import matplotlib.colors as mc # noqa: PLC0415 From 71a282c6ed5f9cfeac5e252e1afc9c8dbda31dec Mon Sep 17 00:00:00 2001 From: Joel Adams Date: Tue, 28 Jul 2026 10:31:18 +0100 Subject: [PATCH 32/32] refactor dataarray tests to use auto close fig fixture with `autouse=True` --- tests/test_epoch_dataarray_accessor.py | 46 ++++++++------------------ 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/tests/test_epoch_dataarray_accessor.py b/tests/test_epoch_dataarray_accessor.py index b889023..4ec4249 100644 --- a/tests/test_epoch_dataarray_accessor.py +++ b/tests/test_epoch_dataarray_accessor.py @@ -26,11 +26,10 @@ TEST_FILES_DIR_3D = download.fetch_dataset("test_files_3D") -@pytest.fixture -def subplots(): - fig, ax = plt.subplots() - yield (fig, ax) - plt.close(fig) +@pytest.fixture(autouse=True) +def close_figs(): + yield + plt.close("all") def test_animation_accessor(): @@ -246,21 +245,21 @@ def test_compute_global_limits_NaNs(): assert result_max == pytest.approx(expected_result_max, abs=1e-1) -def test_epoch_plot_simple_1d_dataset(subplots): +def test_epoch_plot_simple_1d_dataset(): with xr.open_mfdataset( TEST_FILES_DIR_1D.glob("*.sdf"), compat="no_conflicts", join="outer", preprocess=SDFPreprocess(), ) as ds: - _, ax = subplots + _, ax = plt.subplots() ds["Derived_Number_Density_electron"].isel(time=0).epoch.plot(ax=ax) assert len(ax.lines) == 1 assert ax.get_xlabel() == "X [m]" -def test_epoch_plot_simple_2d_dataset(subplots): +def test_epoch_plot_simple_2d_dataset(): with xr.open_mfdataset( TEST_FILES_DIR_2D_MW.glob("*.sdf"), preprocess=SDFPreprocess(), @@ -268,7 +267,7 @@ def test_epoch_plot_simple_2d_dataset(subplots): compat="no_conflicts", join="outer", ) as ds: - _, ax = subplots + _, ax = plt.subplots() ds["Derived_Number_Density_electron"].isel(time=0).epoch.plot(ax=ax) assert len(ax.collections) > 0 @@ -276,9 +275,9 @@ def test_epoch_plot_simple_2d_dataset(subplots): assert ax.get_ylabel() == "Y [m]" -def test_epoch_plot_simple_3d_dataset_slice(subplots): +def test_epoch_plot_simple_3d_dataset_slice(): with xr.open_dataset(TEST_FILES_DIR_3D / "0001.sdf") as ds: - _, ax = subplots + _, ax = plt.subplots() ds["Derived_Number_Density_Electron"].isel(Z_Grid_mid=0).epoch.plot(ax=ax) assert len(ax.collections) > 0 @@ -286,7 +285,7 @@ def test_epoch_plot_simple_3d_dataset_slice(subplots): assert ax.get_ylabel() == "Y [m]" -def test_epoch_plot_flips_axis_order_for_2d_data(subplots): +def test_epoch_plot_flips_axis_order_for_2d_data(): with xr.open_mfdataset( TEST_FILES_DIR_2D_MW.glob("*.sdf"), preprocess=SDFPreprocess(), @@ -294,14 +293,14 @@ def test_epoch_plot_flips_axis_order_for_2d_data(subplots): compat="no_conflicts", join="outer", ) as ds: - _, ax = subplots + _, ax = plt.subplots() ds["Derived_Number_Density_electron"].isel(time=0).epoch.plot(ax=ax) assert ax.get_xlabel() == "X [m]" assert ax.get_ylabel() == "Y [m]" -def test_epoch_plot_flips_axis_order_for_2d_data_with_additional_params(subplots): +def test_epoch_plot_flips_axis_order_for_2d_data_with_additional_params(): with xr.open_mfdataset( TEST_FILES_DIR_2D_MW.glob("*.sdf"), preprocess=SDFPreprocess(), @@ -309,7 +308,7 @@ def test_epoch_plot_flips_axis_order_for_2d_data_with_additional_params(subplots compat="no_conflicts", join="outer", ) as ds: - _, ax = subplots + _, ax = plt.subplots() ds["Derived_Number_Density_electron"].isel(time=0).epoch.plot( ax=ax, xlim=(0.5, 1.0), @@ -351,12 +350,6 @@ def _make_3d_da(shape=(4, 5, 6)): ) -@pytest.fixture -def close_figs(): - yield - plt.close("all") - - def test_recover_vertex_coord_size(): mid = xr.DataArray(np.linspace(0.5, 4.5, 5)) vertex = sxp._recover_vertex_coord(mid) @@ -385,14 +378,12 @@ def test_shift_cmap_asymmetric_center(): assert len(result.colors) == 200 -@pytest.mark.usefixtures("close_figs") def test_voxel_plot_returns_fig_and_ax(): da = _make_3d_da() _, ax = sxp.voxel_plot(da) assert isinstance(ax, Axes3D) -@pytest.mark.usefixtures("close_figs") def test_voxel_plot_accepts_axes(): da = _make_3d_da() _, ax = plt.subplots(figsize=(8, 6), subplot_kw={"projection": "3d"}) @@ -400,7 +391,6 @@ def test_voxel_plot_accepts_axes(): assert isinstance(ax, Axes3D) -@pytest.mark.usefixtures("close_figs") def test_voxel_plot_axis_labels(): da = _make_3d_da() _, ax = sxp.voxel_plot(da) @@ -409,7 +399,6 @@ def test_voxel_plot_axis_labels(): assert ax.get_zlabel() == "Z [m]" -@pytest.mark.usefixtures("close_figs") def test_voxel_plot_default_axis_limits(): da = _make_3d_da() _, ax = sxp.voxel_plot(da) @@ -421,7 +410,6 @@ def test_voxel_plot_default_axis_limits(): assert zlim[0] < zlim[1] -@pytest.mark.usefixtures("close_figs") def test_voxel_plot_with_xlim_ylim_zlim(): da = _make_3d_da() x0, x1 = 2e-6, 8e-6 @@ -433,21 +421,18 @@ def test_voxel_plot_with_xlim_ylim_zlim(): assert ax.get_zlim() == pytest.approx((z0, z1), rel=0.1) -@pytest.mark.usefixtures("close_figs") def test_voxel_plot_with_explicit_vmin_vmax(): da = _make_3d_da() _, ax = sxp.voxel_plot(da, vmin=0.2, vmax=0.8) assert isinstance(ax, Axes3D) -@pytest.mark.usefixtures("close_figs") def test_voxel_plot_with_vcenter(): da = _make_3d_da() _, ax = sxp.voxel_plot(da, cmap="RdBu", vcenter=1e-2) assert isinstance(ax, Axes3D) -@pytest.mark.usefixtures("close_figs") def test_voxel_plot_with_custom_mask(): da = _make_3d_da() mask = da.values > 0.5 @@ -455,7 +440,6 @@ def test_voxel_plot_with_custom_mask(): assert isinstance(ax, Axes3D) -@pytest.mark.usefixtures("close_figs") def test_voxel_plot_aspect_auto(): da = _make_3d_da() _, ax = sxp.voxel_plot(da, aspect="auto") @@ -472,7 +456,6 @@ def test_voxel_plot_aspect_auto(): assert box[2] / box[0] == pytest.approx(z_range / x_range, rel=0.05) -@pytest.mark.usefixtures("close_figs") def test_voxel_plot_aspect_custom_tuple(): da = _make_3d_da() _, ax = sxp.voxel_plot(da, aspect=(1.0, 2.0, 3.0)) @@ -481,7 +464,6 @@ def test_voxel_plot_aspect_custom_tuple(): assert box[2] / box[0] == pytest.approx(3.0, rel=0.01) -@pytest.mark.usefixtures("close_figs") def test_epoch_plot_dispatches_to_voxel_for_3d_spatial_data(): with xr.open_dataset(TEST_FILES_DIR_3D / "0001.sdf") as ds: da = ds["Derived_Number_Density_Electron"].isel(