Written and maintained by CASRAI Editorial Board
Last updated
“SciPy rotate” usually means scipy.ndimage.rotate, the function that rotates an image or any n-dimensional array by an angle in degrees. It has a second meaning: scipy.spatial.transform.Rotation, which rotates 3D vectors using Euler angles, rotation vectors or quaternions. The table below tells you which one you need, and the rest of this guide covers ndimage.rotate in detail, including what reshape, order and mode do to your output.
Which SciPy rotation do you need?
| Task | Use | Angle input |
|---|---|---|
| Rotate an image or array on its pixel grid | scipy.ndimage.rotate(input, angle, ...) |
A float, in degrees |
| Rotate 3D vectors or build an orientation | scipy.spatial.transform.Rotation |
Euler angles, rotation vectors, quaternions or rotation matrices, created with from_... methods |
The Rotation class is created through its from_... methods rather than by calling Rotation(...) directly. For example, from scipy.spatial.transform import Rotation as R followed by r = R.from_euler('z', 90, degrees=True) builds a 90 degree rotation about the z axis, and r.apply(vectors) rotates the vectors.
What it is used for in research
scipy.ndimage.rotate is used where array data has to be brought into a common orientation before measurement: aligning microscopy or scan images, straightening a tilted specimen, or generating rotated copies of an image to test whether an analysis depends on orientation. It works on arrays of any dimension, not only photographs, and it interpolates, so the output values are resampled rather than copied. If you need an exact 90 degree turn with no resampling, NumPy’s rot90 is the better fit (see the alternatives table below). For the wider SciPy toolkit, see the CASRAI guides on SciPy interpolation, SciPy signal processing and SciPy statistics.
Install or access (official source only)
The SciPy project’s install page at scipy.org lists these commands:
- pip:
python -m pip install scipy - conda:
conda install scipy - mamba:
mamba install scipy
Then import the function with from scipy import ndimage. The sample image used in the SciPy documentation example comes from scipy.datasets.
Step-by-step: rotate an array with ndimage.rotate
The signature in the current SciPy reference is:
scipy.ndimage.rotate(input, angle, axes=(1, 0), reshape=True, output=None, order=3, mode='constant', cval=0.0, prefilter=True)
- Load your array. The documentation example uses
from scipy import datasets, ndimageandimg = datasets.ascent(), a 512 by 512 array. Use your own NumPy array in its place. - Choose the angle.
angleis a float in degrees. - Decide whether the output keeps the input shape. By default
reshape=True, which adjusts the output shape so the entire input fits. Passreshape=Falseto keep the original shape. - Call the function.
rotated = ndimage.rotate(img, 45, reshape=False) - Check the shape.
rotated.shapereturns(512, 512)withreshape=False. Withreshape=True, the same 45 degree rotation returns(724, 724)in the documentation example.
The axes argument is a tuple of two integers that selects the plane of rotation; its default is (1, 0), the first two axes. For an array with more than two dimensions, set axes explicitly if the plane you want to rotate is not the first two axes.
Output and how to read it
The function returns an ndarray. By default output is None and the result has the same dtype as the input; you can pass an array or a dtype to output to change that. Three arguments decide what the rotated array looks like.
reshape: cropped corners or a larger canvas
With reshape=False the output keeps the input shape, so the corners of a rotated image fall outside the array and are cut off. With reshape=True nothing is lost, and the array grows: 512 by 512 became 724 by 724 for a 45 degree angle in the SciPy example.
mode and cval: what fills the empty areas
Rotation leaves regions with no source pixels. mode controls how points outside the input boundaries are filled. The documented options are reflect (the same as grid-mirror), constant, grid-constant, nearest, mirror, grid-wrap and wrap. The default is constant, which fills with cval (default 0.0) and does no interpolation past the edges; grid-constant also fills with cval but does interpolate past the edges.
order and prefilter: interpolation quality
order is the spline interpolation order, from 0 to 5, with a default of 3. prefilter defaults to True; when order is greater than 1 it creates a temporary float64 array. Setting it to False slightly blurs the result for orders above 1 unless the input is already prefiltered.
Complex input
For complex input the real and imaginary parts are rotated independently (support added in SciPy 1.6.0).
Troubleshooting
The corners of my image are cut off
You passed reshape=False. Use the default reshape=True so the output shape is adjusted to contain the whole input.
The output is larger than the input
That is the default reshape=True behaviour. Use reshape=False if your pipeline needs a fixed shape.
Black borders appear around the image
The default mode='constant' with cval=0.0 fills empty areas with zero. Set cval to another value, or choose a mode such as nearest or reflect.
The result looks blurred
Interpolation resamples the data. Check order (default 3) and leave prefilter=True unless the input is already prefiltered. Order 0 is the lowest interpolation order in the documented range.
The wrong plane was rotated
Set axes explicitly. The default (1, 0) uses the first two axes of the array.
The output values have an unexpected type
The output defaults to the input dtype. Pass output with the dtype you want.
Free alternatives
| Option | What the official documentation says |
|---|---|
numpy.rot90(m, k=1, axes=(0, 1)) |
Rotates an array by 90 degrees in the plane given by axes, k times. For a 2D array with default arguments the rotation is counterclockwise. It returns a rotated view of m, not a copy. |
skimage.transform.rotate (scikit-image) |
Signature rotate(image, angle, resize=False, center=None, order=None, mode='constant', cval=0, clip=True, preserve_range=False). The angle is in degrees and positive values rotate counter-clockwise. resize defaults to False, and you can set the rotation center. |
scipy.spatial.transform.Rotation |
Rotation in 3 dimensions, built from quaternions, rotation matrices, rotation vectors or Euler angles; for vectors, not image grids. |
Note one difference in defaults: scipy.ndimage.rotate has reshape=True, while skimage.transform.rotate has resize=False. If you move code between the two, check the output shape. For related array work, see NumPy convolve and the overview of Python for data analysis.
FAQ
What does scipy.ndimage.rotate do?
It rotates an array by an angle in degrees in the plane given by axes, resampling with spline interpolation of the chosen order.
Is the angle in degrees or radians?
Degrees, as a float, for ndimage.rotate. For spatial.transform.Rotation, methods such as from_euler take a degrees=True option to say the angles are in degrees.
How do I keep the original image size?
Pass reshape=False.
Can it rotate 3D vectors?
Not ndimage.rotate. Use scipy.spatial.transform.Rotation and its apply method.
Does it work on complex arrays?
Yes. The real and imaginary parts are rotated independently.
Sources (official docs)
- SciPy reference, scipy.ndimage.rotate, checked 2026-10-29.
- SciPy reference, scipy.spatial.transform.Rotation, checked 2026-10-29.
- SciPy project, Installing SciPy, checked 2026-10-29.
- NumPy reference, numpy.rot90, checked 2026-10-29.
- scikit-image API, skimage.transform, checked 2026-10-29.







