Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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.
