Full Changelog#
2.3.2 (2025-06-12)#
Bug Fixes#
- Removed the check for compatible coordinate systems within - reproject_toas it was redundant. (#833)
Internal Changes#
- Make - MatplotlibPlotteronly add data to line plots if at least one value of the data is unmasked and finite. (#802)
2.3.1 (2025-02-11)#
Documentation#
- Fixed a typo in the docstring of - data.
2.3.0 (2025-01-14)#
Breaking Changes#
- “dimensions” property on ~ndcube.NDCube` and - NDCubeSequencehave been deprecated and replaced by “shape” (#684)
Removals#
- The ability to create an - NDCollectionobject with numerical keys is deprecated as it leads to ambiguous behavior when slicing the collection. (#778)
New Features#
- Add Sliceable - NDMetaclass for axis-associated metadata. (#455)
- Added a new - squeezemethod to- ndcube.NDCube. It will remove all axes of length 1. (#669)
- Added - quantityattribute to- NDCubeto return the data array with in the cube with the physical units stored in the- unitattribute. (#677)
- Added - ndcube.NDCube.shapeas a replacement for “dimensions”. (#684)
- Enable rtruediv on - NDCubesuch that a user can now do 1/- NDCube. (#685)
- Add a - keepdims=Falsekwarg to- cropand- crop_by_valuessetting to true keeps length-1 dimensions default behavior drops these dimensions. (#732)
- When calling - ndcube.NDCubeBase.axis_world_coords()or- ndcube.NDCubeBase.axis_world_coords_values()with a specific axis or axes specified, the methods now avoid doing calculations for any other uncorrelated axes, offering significant speedups when those other axes are large. (#767)
- Add support for passing - -1as an element of the- bin_shapeargument to- NDCube.rebinwhich will not rebin along that dimension (sets the bin shape to equal the data shape). (#777)
- It is now possible to set the - NDCube.dataproperty of a cube with an array of the same shape and unit as the current cube. (#795)
Bug Fixes#
- ndcube.NDCube.rebin()- bin_shapeargument now accepts a- astropy.units.Quantityas input if the units are convertible to pixels. (#744)
- Fix support for astropy 7.0, this involved a change to - CompoundLowLevelWCSso that in handles- pixel_boundsif only one component WCS sets a pixel bound. (#772)
- Fixed a bug which caused - NDCubeSequence.cube_like_dimensionsto break. (#788)
- Added an internal code to shortcut non-correlated axes avoiding the creation of a full coordinate grid, reducing memory use in specific circumstances. (#798) 
Documentation#
- Added a gallery example (Combining a celestial WCS with a wavelength axis) showcasing how to create a visualisation of unevenly spaced wavelength data cube using AIA data. (#691) 
- Added a gallery example (How to create an GWCS from quantities and times) showcasing how to create a GWCS from quantities. (#695) 
Internal Changes#
- Move code creating a masked array for - ndcube.NDCube.rebinto a private function which is then called by- ndcube.NDCube.rebin. (#705)
- Added explicit support for numpy 2.0. (#729) 
2.2.0 (2023-11-16)#
Backwards Incompatible Changes#
- ndcube.NDCollection.aligned_axesattribute is now property. (#607)
- Dropped Python 3.8 support 
- Increased minimum required for - astropyto 5.0
- Increased minimum required for - numpyto 1.21
- Increased minimum required for - gwcsto 0.18. (#636)
Features#
- Provides - unwrap_wcs_to_fitswcs, a function to create a- astropy.wcs.WCSinstance equivalent to a sliced and/or resampled WCS instance. Only valid if the underlying implementation of the wrapped WCS instance is also an- astropy.wcs.WCSinstance. (#649)
Bug Fixes#
- Fix docstring causing doc build problems for some users. (#600) 
- Fixes a bug where passing a string representation of a unit to - ndcube.NDCube.toraised a- TypeError. (#605)
- Keywords for - sequence_axis_coordsand- sequence_axis_unitwere not passed to the- SequenceAnimatorconstructor. This is now fixed. (#607)
- Adds - Nonecheck on- self.aligned_axesto- NDCollection.copy()and- NDCollection.pop()which raised a- AttributeError(#646)
Trivial/Internal Changes#
- Updated the error messages when missing either - matplotlibor- mpl_animatorswhen creating a plot. (#651)
v2.1.0 (2023-03-01)#
Backwards Incompatible Changes#
- To support compatibility with reproject 0.9, the API of - NDCube.reproject_tohas been tweaked so that any keyword argument to the underlying reprojection function can be passed through. This has the effect of being a breaking change if you were specifying any arguments after- shape_out=as positional rather than keyword arguments. (Note that in a future release we will probably change to require keyword arguments to- reproject_to. (#552)
Features#
- Implement new property, - ndcube.ExtraCoords.is_emptythat returns- Trueif the object has got extra coords. Otherwise return- False. (#450)
- Add - ndcube.ExtraCoords.resamplemethod to resample extra coordinates by a certain factor in each array dimension. (#450)
- Implement a new - ndcube.NDCube.rebin()method to combine integer numbers of pixels along each axis into larger pixels. (#450)
- Add new methods to interpolate lookup table coordinates: - ndcube.extra_coords.table_coord.QuantityTableCoordinate.interpolate,- ndcube.extra_coords.table_coord.SkyCoordTableCoordinate.interpolate,- ndcube.extra_coords.table_coord.TimeTableCoordinate.interpolate,- ndcube.extra_coords.MultipleTableCoordinate.interpolate(#450)
- Add - ndcube.NDCubeSequence.cropand- ndcube.NDCubeSequence.crop_by_valuesmethods which crop the- NDCubeSequencebased on input world coordinate ranges. (#466)
- Add basic arithmetic methods between - NDCubeobjects and broadcastable arrays, scalars, and- Quantityobjects. Operations between two- NDCubeobjects are not supported. (#541)
- Add - ndcube.NDCube.toto convert cube to new unit. (#586)
- Created - GlobalCoordsABCand updated- NDCubeABC, and- ExtraCoordsABCto reflect official NDCube 2 API definition in SEP. (#592)
Bug Fixes#
- Fix bug #535 where - NDCollectioncould not update when- aligned_axesis- None(#538)
- Fix a bug where - aligned_axis_physical_typescaused- __str__to error when- aligned_axeswas- None. (#539)
- Fix a bug where - data_unitwas not being correctly passed through to the underlying plotting function when animating a cube. (#578)
Improved Documentation#
- Add example to example gallery of how to create an NDCube from a FITS file. (#544) 
v2.0.3 (2022-09-23)#
Bug Fixes#
- Dynamically copy docstring and function signature from - ndcube.NDCube.plotter.plotto- ndcube.NDCube.plot(). (#534)
- Fixed a bug where the - plot_axeskey was not respected when passing- axesto- plotfor 2D cubes. (#551)
- Limit maximum reproject version to 0.9 due to API changes. ndcube 2.1 will support the new reproject keyword arguments. (#564) 
v2.0.2 (2022-05-10)#
Bug Fixes#
- Fix a bug in the - NDCube._as_mpl_axesimplementation, allowing cubes with compatible dimensions to be passed as the- projection=keyword argument to certain matplotlib functions again. (#509)
Trivial/Internal Changes#
- Remove use of deprecated - distutilsmodule. (#520)
2.0.1 (2021-11-19)#
Bug Fixes#
- Enable - NDCollectionto accept aligned axes inputs in any integer type. (#495)
- Patch to convert quantity objects passed to - crop_by_coordsto the units given in the- wcs.world_axis_units. (#497)
- Fix a bug which prevented the - axes_units=kwarg from working when using the matplotlib animators. (#498)
- Add support for length-1 lookup table coords within extra coords. (#499) 
- Bump the minimum version of astropy to 4.2 to correctly support capturing dropped world dimensions into global coords when slicing the WCS. (#500) 
2.0.0 (2021-10-29)#
Backwards Incompatible Changes#
- Remove unused util functions and the ndcube WCS class. Refactor util functions for converting between between data and WCS indices to reflect the APE14 nomenclature that distinguishes between array, pixel and world axes. (#280) 
- NDCubeSequence animation axes can no longer be set by extra coords. (#294) 
- ImageAnimatorNDCubeSequence, ImageAnimatorCubeLikeNDCubeSequence, LineAnimatorNDCubeSequence and LineAnimatorCubeLikeNDCubeSequence have been removed and replaced by NDCubeSequenceAnimator. (#294) 
- Change type of output of - ndcube.NDCollection.aligned_world_axis_physical_typesfrom tuple to list. This is to be consistent with output of- astropy.wcs.WCS.world_axis_physical_types. (#302)
- Change output type when common axis item is a slice that covers only one subcube. Previously this would return an NDCube. Now an NDCubeSequence is always returned unless the common axis item is an integer. Also, refactor NDCubeSequence.index_as_cube so codebase is simpler. (#311) 
- Replace NDCube.crop_by_coords and NDCube.crop_by_extra_coords with new method, NDCube.crop (#316) 
- Remove NDCubeSequence plotting. (#322) 
- Update - NDCube.array_axis_physical_typesreturn physical types from extra coords as well as the WCS. (#338)
- Rename - ndcube.ExtraCoords.addmethod from previous name “add_coordinate”. (#394)
- The - NDCubeobject no longer inherits from- astropy.nddata.NDArithmeticMixinas the methods were not coordinate aware. (#457)
Deprecations and Removals#
- Remove - NDCube.pixel_to_worldand- NDCube.world_to_pixel. (#300)
- Remove - world_axis_physical_typesmethods from- NDCubeand- NDCubeSequence. (#302)
- Remove - NDCubeSequence.sequence_axis_extra_coords. This is replaced by- NDCubeSequence.sequence_axis_coords. (#335)
- Remove - ndcube.NDCubeSequence.common_axis_extra_coords. Will be replaced by- ndcube.NDCubeSequence.common_axis_coords. (#344)
- Remove - NDCollection.aligned_world_axis_physical_types. It will be replaced by- aligned_axis_physical_types. (#347)
Features#
- Implement a new - ndcube.ExtraCoordsclass which allows the specification of extra coordinates via lookup tables or WCS. This class exposes the extra coords as an APE 14 WCS object. (#271)
- Add new method, - ndcube.NDCube.axis_world_coord_values, to return world coords for all pixels for all axes in WCS as quantity objects. (#279)
- Added a new method - ndcube.NDCube.array_axis_physical_typesto show which physical types are associated with each array axis. (#281)
- Add properties to NDCubeSequence giving the world physical types for each array axis. (#301) 
- Add as_mpl_axes method to NDCube plotting mixin so the an NDCube can be provided to astropy WCSAxes as a projection. (#314) 
- Make pyplot colorbar work with the output on NDCube.plot when it is a 2D image. (#314) 
- Introduce a new class, - GlobalCoords, for holding scalar coordinates that don’t apply to any pixel axes. (#323)
- Implement - ndcube.NDCube.axis_world_coordswhich returns high level coordinate objects for all, or a subset of, axes. (#327)
- New property, NDCubeSequence.sequence_axis_coords creates lists of GlobalCoords from each NDCube in the sequence. This replaces NDCubeSequence.sequence_axis_extra_coords, but because it uses the GlobaCoords infrastructure, can handle more than just coords that began as extra coords. (#335) 
- Implement - ndcube.NDCubeSequence.common_axis_coordsto replace- ~ndcube.NDCubeSequence.common_axis_extra_coords. In contrast to old property, this new property collates coordinates from the wcs as well as extra_coords. (#344)
- New property, - ndcube.NDCollection.aligned_axis_physical_types. This replaces- ~ndcube.NDCollection.aligned_world_axis_physical_typesand returns a list of tuples, where each tuple gives the physical types common between all members of the collection for a given aligned axis. (#347)
- Allow - ndcube.NDCubeSequence.explode_along_axisto explode sequence along any axis, not just the common axis. (#358)
- Plotting functionality on - NDCubehas been refactored to use pluggable “plotter” classes. All plotting functionality can now be accessed via the- ndcube.NDCube.plotterattribute, with- ndcube.NDCube.plotbecoming an alias for- ndcube.NDCube.plotter.plot.- Advanced users, or package maintainers that which to customise the plotting functionality of an - NDCubeinstance can set the- .plotterattribute of a cube to be a subclass of- ndcube.visualization.BasePlotterwhich then customises the behaviour of the- ndcube.NDCube.plot()method and provides any other methods implemented on the plotter. (#401)
- Preserve sliced-out coordinates from WCS in the GlobalCoords instance. (#402) 
- Enable instantiating an NDCube from an existing NDCube by copying extra/global coords. (#404) 
- Support exposing dropped dimensions when - ExtraCoordsis sliced. (#411)
- ExtraCoordsis now explicitly limited to one dimensional tables because of a limitation in our use of- astropy.modeling. (#414)
- Adds functionality to reproject an - NDCubeobject to coordinates described by another WCS or FITS Header by calling the new- reproject_tomethod. (#434)
- Change the - edges=keyword to- pixel_corners=in- ndcube.NDCube.axis_world_coords()and- ndcube.NDCube.axis_world_coords_valuesto make its meaning clearer based on SEP feedback. (#437)
- axis_world_coordsand- axis_world_coords_valuesnow use a different, substantially faster and more memory efficient algorithm to generate the coordinates along all axes. (#442)
- Extends - ndcube.NDCube.reproject_tofunctionality by supporting- adaptiveand- exactalgorithms for an- NDCubewith 2D celestial WCS. (#448)
- Introduce optional offset between old and new pixel grids in - ndcube.wcs.wrappers.resampled_wcs.ResampledLowLevelWCS. (#449)
- ndcube.ExtraCoords.from_lookup_tablesaccepts (a sequence of)- physical_typesas kwarg to set the types of its- lookup_tables. (#451)
- Create new plotter class for animating - NDCubeSequenceis the 2.0 framework. This class always sets the sequence axis as a slider and leverages- ndcube.NDCube.plot. (#456)
- Add - __len__method to- NDCubeSequencewhich makes- len(sequence)return the number of cubes in the sequence. (#464)
- Add - __iter__method to- NDCubeSequencewhich iterates through the cubes within the sequence. (#465)
- Add property to - ExtraCoordsthat returns a WCS of extra coords that describes all axes of associated cube. (#472)
Bug Fixes#
- Fix - ndcube.NDCollection.aligned_dimensionsso it does not crash when components of collection are NDCubeSequences. (#264)
- Generalize int type checking so it is independent of the bit-type of the OS. (#269) 
- Fix - axis_world_coord_valueswhen the WCS is 1D and ensure it always returns Quantities (#287)
- Change name of - NDCube.axis_world_coord_valuesto- NDCube.axis_world_coords_valuesto be consistent with NDCube.axis_world_coords (#293)
- Remove NDCubeSequence animation dependence of deprecated sunpy ImageAnimator and LineAnimator classes in favour of ArrayAnimatorWCS class. (#294) 
- Fix bug whereby common axis was not updated appropriately when slicing an NDCubeSequence. (#310) 
- Fix bug in - NDCube.axis_world_coords_valueswhen number of pixel and world dimensions differ. (#319)
- Fixes bug in - array_indices_for_world_objectswhen the WCS input does not have a world_axis_object_components attribute. The fix causes the low_level_wcs version is tried before the code fails. This enables- ndcube.NDCube.combined_wcsto be used with this function. (#344)
- Fixes IndexError in - array_indices_for_world_objectswhich occurred when some of the world axes are dependent. (#344)
- Stop - ndcube.NDCube.explode_along_axissetting a common axis to the output- NDCubeSequence. The output sequence should have no common axis. (#358)
- Enable 2-D NDCubes to be visualized as a 1-D animated line. (#381) 
- Ensure corner inputs to - ndcube.NDCube.crop()are converted to units stored in WCS as- world_to_array_index_valuesdoes not handle units. (#382)
- updated ndcube github repository link in “ndcube.docs.installation.rst”. (#392) 
- Fix bug in NDCube.axis_world_coords_values when axes_coords is initially a bare astropy coordinate object rather than a list/tuple of coordinate objects. (#400) 
- Change the implementation of - NDCube.cropso that it takes into account all the corners of the world region specified by the upper and lower corners, not just those two points. (#438)
- Ensure - NDCubeinit forces WCS to become high level.- This patches a bug in astropy. (#447) 
- Fix bug in - axis_world_coords_valueswhich caused the units to be stripped when an- axesinput was given. (#461)
- Fix bug in - get_dependent_world_axeswhere an erroneous matrix transpose caused an error for non-square axis correlation matrices and wrong results for diagonally non-symmetric ones. (#471)
- Extend support for cropping an - NDCubeusing an- ExtraCoordsinstance as the wcs. (#472)
- Fix check as to whether user inputs to - ndcube.wcs.wrappers.CompoundLowLevelWCS.world_to_pixel_valuesresult in consistent pixel values when world dimensions share pixel dimensions. Previously this check was unreliable when non-trivial mapping between world and pixel dimensions was used. (#472)
- Fix slicing - ExtraCoordsmade of lookup tables. This bug meant that mapping of coords to arrays axes was not adjusted when an axis was dropped. (#482)
Improved Documentation#
- Document accepted input to - lookup_tablein- ExtraCoordssetting its- physical_types. (#451)
- Improved information and formatting of - __str__methods. (#453)
Trivial/Internal Changes#
- Simplify and speed up implementation of NDCubeSequence slicing. (#251) 
- Fix docstring formatting to help docs build. (#262) 
- Use pytest-mpl for figure tests. (#312) 
- Port the tests for NDCube to use pytest fixtures (#318) 
- Allow corner inputs to - crop()to not be wrapped in a- tupleis only one high level coordinate objects required. (#380)
- Make sunpy an optional dependence. Without it, the _animate_cube plotting functionality will be disabled. (#393) 
- Adds a function to compare the physical types of two WCS objects. (#433) 
- Propagate reference to NDCube object through - ExtraCoordsstring slicing. (#454)
- Adds a function to identify invariant axes between two WCS objects. (#459) 
- The matplotlib animators code has been moved from - sunpyto a new package- mpl_animatorsso ndcube no longer has an optional dependency on sunpy. (#484)
1.3.0 (2020-03-27)#
Features#
- Add new NDCollection class for linking and manipulating partially or non-aligned NDCubes or NDCubeSequences. (#238) 
Bug Fixes#
- Fixed the files included and excluded from the tarball. (#212) 
- Fix crashing bug when an NDCube axis after the first is sliced with a numpy.int64. (#223) 
- Raises error if NDCube is sliced with an Ellipsis. (#224) 
- Changes behavior of NDCubeSequence slicing. Previously, a slice item of interval length 1 would cause an NDCube object to be returned. Now an NDCubeSequence made up of 1 NDCube is returned. This is consistent with how interval length 1 slice items slice arrays. (#241) 
1.2.0 (2019-09-10)#
Features#
- Changed all instances of “missing_axis” to “missing_axes” (#157) 
- Added a feature to get the pixel_edges from - ndcube.NDCube.axis_world_coords()(#174)
Bug Fixes#
- ndcube.NDCube.wcs.world_axis_physical_typesnow sets the axis label to the WCS CTYPE if no corresponding IVOA name can be found. (#164)
- Fixed the bug of using - pixel_edgesinstead of- pixel_valuesin plotting (#176)
- Fix 2D plotting from crashing when both data and WCS are 2D. (#182) 
- Fix the ability to pass a custom Axes to - ndcube.NDCube.plotfor a 2D cube. (#204)
Trivial/Internal Changes#
1.1#
API-Breaking Changes#
- ~ndcube.NDCubeBase.crop_by_extra_coordAPI has been broken and replaced. Old version:- crop_by_extra_coord(min_coord_value, interval_width, coord_name). New version:- crop_by_extra_coord(coord_name, min_coord_value, max_coord_value). [#142]
New Features#
- Created a new - NDCubeBasewhich has all the functionality of- NDCubeexcept the plotting. The old- NDCubeBasewhich outlined the- ndcube.NDCubeAPI was renamed- NDCubeABC.- ~ndcube.NDCubehas all the same functionality as before except is now simply inherits from- ~ndcube.NDCubeBaseand- ~ndcube.mixins.plotting.NDCubePlotMixin. [#101]
- Moved NDCubSequence plotting to a new mixin class, NDCubSequencePlotMixin, making the plotting an optional extra. All the non-plotting functionality now lives in the NDCubeSequenceBase class. [#98] 
- Created a new - ~ndcube.NDCubeBase.explode_along_axismethod that breaks an NDCube out into an NDCubeSequence along a chosen axis. It is equivalent to- explode_along_axis. [#118]
- NDCubeSequence plot mixin can now animate a cube as a 1-D line if a single axis number is supplied to plot_axis_indices kwarg. 
API Changes#
- Replaced API of what was previously - utils.wcs.get_dependent_axes, with two new functions,- utils.wcs.get_dependent_data_axesand- utils.wcs.get_dependent_wcs_axes. This was inspired by a new implementation in- glue-vizwhich is intended to be merged into- astropyin the future. This API change helped fix the- NDCube.world_axis_physical_typebug listed below. [#80]
- Give users more control in plotting both for NDCubePlotMixin and NDCubeSequencePlotMixin. In most cases the axes coordinates, axes units, and data unit can be supplied manually or via supplying the name of an extra coordinate if it is wanted to describe an axis. In the case of NDCube, the old API is currently still supported by will be removed in future versions. [#98 #103] 
Bug Fixes#
- Allowed - axis_world_coordsto accept negative axis indices as arguments. [#106]
- Fixed bug in - NDCube.crop_by_coordsin case where real world coordinate system was rotated relative to pixel grid. [#113].
- ~ndcube.NDCubeBase.world_axis_physical_typesis now not case-sensitive to the CTYPE values in the WCS. [#109]
- ~ndcube.NDCubeBase.plotnow generates a 1-D line animation when image_axis is an integer.
1.0.1#
New Features#
- Added installation instructions to docs. [#77] 
Bug Fixes#
- Fixed bugs in - NDCubeSequenceslicing and- NDCubeSequence.dimensionsin cases where sub-cubes contain scalar- .data. [#79]
- Fixed - NDCube.world_axis_physical_typesin cases where there is a- missingWCS axis. [#80]
- Fixed bugs in converting between negative data and WCS axis numbers. [#91] 
- Add installation instruction to docs. [#77] 
- Fix function name called within NDCubeSequence.plot animation update plot. [#95] 
