Recently, I was working on an image processing project where I needed to rotate images at specific angles for data augmentation. The SciPy library offers a powerful function called ndimage.rotate that makes this task incredibly simple.
In this article, I’ll cover multiple ways to rotate images using this function, including handling different interpolation modes and preserving the original dimensions.
So let’s dive in!
Understand ndimage.rotate Basics
The ndimage.rotate function from SciPy is designed to rotate an image array by a specified angle in degrees. It’s extremely versatile and handles both 2D and 3D arrays, making it perfect for rotating grayscale or color images.
Here’s a simple example to rotate an image by 45 degrees:
from scipy import ndimage
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
# Load an image
image = np.array(Image.open('golden_gate.jpg'))
# Rotate the image by 45 degrees
rotated_image = ndimage.rotate(image, 45)
# Display the original and rotated images
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image)
plt.title('Original Image')
plt.subplot(1, 2, 2)
plt.imshow(rotated_image)
plt.title('Rotated Image (45 degrees)')
plt.show()I executed the above example code and added the screenshot below.

Different Methods to Rotate Images
Now, I will explain to you the methods to rotate images.
Read Python SciPy Freqz
Method 1 – Basic Rotation with Default Parameters
The simplest way to use ndimage.rotate is with just the image and angle parameters:
rotated_image = ndimage.rotate(image, 45)By default, this will:
- Rotate the image counterclockwise by the specified angle
- Use cubic spline interpolation
- Resize the output image to accommodate the rotated content
Method 2 – Preserve Image Size
Sometimes you want to maintain the original image dimensions after rotation. You can do this with the reshape parameter:
# Rotate without resizing the output
rotated_image = ndimage.rotate(image, 30, reshape=False)This is particularly useful when you’re processing batches of images that need to remain the same size, like in machine learning applications.
Method 3 – Controll Interpolation Mode
The quality of your rotated image can be controlled by changing the interpolation order:
# Nearest neighbor interpolation (order=0)
rotated_nearest = ndimage.rotate(image, 45, order=0)
# Bilinear interpolation (order=1)
rotated_bilinear = ndimage.rotate(image, 45, order=1)
# Cubic interpolation (order=3, default)
rotated_cubic = ndimage.rotate(image, 45, order=3)
# Display all interpolation modes
plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.imshow(rotated_nearest)
plt.title('Nearest Neighbor')
plt.subplot(1, 3, 2)
plt.imshow(rotated_bilinear)
plt.title('Bilinear')
plt.subplot(1, 3, 3)
plt.imshow(rotated_cubic)
plt.title('Cubic')
plt.show()I executed the above example code and added the screenshot below.

The interpolation order affects how pixels are calculated in the rotated image:
order=0: Nearest-neighbor interpolation (fastest but lowest quality)order=1: Bilinear interpolation (good balance)order=3: Cubic interpolation (highest quality but slowest)
Method 4 – Handle Edge Pixels with Mode
When rotating an image, new pixels are created at the edges. You can control how these are filled using the mode parameter:
# Rotate with different edge handling modes
rotated_constant = ndimage.rotate(image, 45, mode='constant', cval=0)
rotated_nearest = ndimage.rotate(image, 45, mode='nearest')
rotated_reflect = ndimage.rotate(image, 45, mode='reflect')
# Display different modes
plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.imshow(rotated_constant)
plt.title('Constant (Black)')
plt.subplot(1, 3, 2)
plt.imshow(rotated_nearest)
plt.title('Nearest')
plt.subplot(1, 3, 3)
plt.imshow(rotated_reflect)
plt.title('Reflect')
plt.show()I executed the above example code and added the screenshot below.

Common mode options include:
'constant': Fill with a constant value (specified bycval, default is 0)'nearest': Fill with the nearest edge value'reflect': Reflect the image at the boundaries'wrap': Wrap the image values at the boundaries
Check out Python SciPy Confidence Interval
Method 5 – Rotate Around a Specific Center Point
By default, ndimage.rotate rotates around the center of the image. You can specify a different center using the center parameter:
# Rotate around a specific point (top-left corner in this case)
h, w = image.shape[:2]
rotated_corner = ndimage.rotate(image, 45, center=(0, 0))
# Rotate around the center (default behavior)
rotated_center = ndimage.rotate(image, 45)
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(rotated_corner)
plt.title('Rotated around top-left corner')
plt.subplot(1, 2, 2)
plt.imshow(rotated_center)
plt.title('Rotated around center')
plt.show()Practical Example: Create a Panorama Effect
Here’s a practical example where I use ndimage.rotate to create a panorama-like effect by rotating an image slightly in multiple steps:
import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt
from PIL import Image
# Load an image of the New York City skyline
image = np.array(Image.open('nyc_skyline.jpg'))
# Create a list to store rotated images
rotated_images = []
# Rotate the image in 10-degree increments from -30 to 30 degrees
for angle in range(-30, 31, 10):
rotated = ndimage.rotate(image, angle, reshape=False, mode='nearest')
rotated_images.append(rotated)
# Display the results
plt.figure(figsize=(15, 8))
for i, img in enumerate(rotated_images):
plt.subplot(2, 4, i+1)
plt.imshow(img)
plt.title(f'Rotation: {-30 + i*10}°')
plt.axis('off')
plt.tight_layout()
plt.show()This technique is often used in computer vision applications for object detection at different orientations or creating augmented datasets for machine learning.
Rotations for Scientific Image Processing
In scientific image processing, precise rotations are crucial. Here’s how you might use ndimage.rotate for microscopy images:
# Load a microscopy image
cell_image = np.array(Image.open('cell_sample.tif'))
# Apply multiple processing steps including rotation
processed_image = ndimage.gaussian_filter(cell_image, sigma=2) # Blur first
processed_image = ndimage.rotate(processed_image, 15, order=3, prefilter=True)
# The prefilter=True option helps preserve details in scientific imagesI hope you found this guide helpful for understanding how to use ndimage.rotate effectively. Whether you’re preprocessing images for machine learning, working on computer vision projects, or just need to align photos properly, this function offers the flexibility and power to get the job done efficiently.
You may like to read other SciPy-related tutorials:

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.