How to change the scale of imshow in matplotlib without stretching the image?

To change the scale of imshow in matplotlib without stretching the image, you need to control the aspect ratio and extent parameters. This prevents distortion when displaying 2D data arrays as images.

Understanding the Problem

By default, matplotlib's imshow() automatically adjusts the image to fill the plot area, which can stretch or compress your data. The aspect and extent parameters give you precise control over scaling.

Basic Example with Aspect Control

Here's how to display an image without stretching using the aspect parameter ?

import numpy as np
import matplotlib.pyplot as plt

# Create sample data
data = np.random.rand(4, 4)

# Create figure with custom size
plt.figure(figsize=(10, 4))

# Original image (default aspect)
plt.subplot(1, 3, 1)
plt.imshow(data, origin='lower')
plt.title('Default (aspect=1)')

# Stretched image (auto aspect)
plt.subplot(1, 3, 2)
plt.imshow(data, origin='lower', aspect='auto')
plt.title('Auto aspect (stretched)')

# Controlled aspect ratio
plt.subplot(1, 3, 3)
plt.imshow(data, origin='lower', aspect=2)
plt.title('Custom aspect=2')

plt.tight_layout()
plt.show()

Using Extent Parameter

The extent parameter maps pixel coordinates to data coordinates, allowing precise control over scaling ?

import numpy as np
import matplotlib.pyplot as plt

# Create sample data
data = np.random.rand(4, 4)

plt.figure(figsize=(12, 4))

# Without extent
plt.subplot(1, 3, 1)
plt.imshow(data, origin='lower')
plt.title('Default coordinates')

# With extent - wider range
plt.subplot(1, 3, 2)
plt.imshow(data, origin='lower', extent=[-4, 4, -1, 1])
plt.title('Extended coordinates')

# With extent and aspect control
plt.subplot(1, 3, 3)
plt.imshow(data, origin='lower', extent=[-4, 4, -1, 1], aspect=4)
plt.title('Extent + aspect=4')

plt.tight_layout()
plt.show()

Practical Example with Real Data

Here's a practical example showing how to display a heatmap with proper scaling ?

import numpy as np
import matplotlib.pyplot as plt

# Create temperature-like data
x = np.linspace(0, 10, 50)
y = np.linspace(0, 5, 25)
X, Y = np.meshgrid(x, y)
temperature = np.sin(X) * np.cos(Y) + np.random.normal(0, 0.1, X.shape)

plt.figure(figsize=(10, 5))

# Method 1: Control aspect ratio
plt.subplot(1, 2, 1)
plt.imshow(temperature, origin='lower', extent=[0, 10, 0, 5], 
           aspect='equal', cmap='coolwarm')
plt.colorbar(label='Temperature')
plt.title('Equal aspect (no stretching)')
plt.xlabel('Distance (km)')
plt.ylabel('Height (km)')

# Method 2: Custom aspect ratio
plt.subplot(1, 2, 2)
plt.imshow(temperature, origin='lower', extent=[0, 10, 0, 5], 
           aspect=2, cmap='coolwarm')
plt.colorbar(label='Temperature')
plt.title('Custom aspect=2')
plt.xlabel('Distance (km)')
plt.ylabel('Height (km)')

plt.tight_layout()
plt.show()

Key Parameters Summary

Parameter Purpose Common Values
aspect Controls width/height ratio 'equal', 'auto', numeric value
extent Maps pixels to data coordinates [left, right, bottom, top]
origin Sets coordinate system origin 'lower', 'upper'

Conclusion

Use aspect='equal' to maintain original proportions, or set a custom numeric aspect ratio. The extent parameter helps map your data to meaningful coordinate ranges without distortion.

---
Updated on: 2026-03-26T14:53:45+05:30

18K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements