-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
imshow with interpolation='bicubic' on downsampled large arrays looks blurred #17490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
|
Are you resampling before or after color mapping? The relevant code is matplotlib/lib/matplotlib/image.py Lines 399 to 510 in 6ed975c
This discussion in #13724 may also be of interest. Without a minimal example to test with or any context as to how you generated your second image there isn't much we can do to help you. |
Thank you so far. I checked and its not a resultion / windows magnification issue. The other hint of how the image is resampled gets closer. However, I'm a user and don't know where to find the "_resample" code. Code for reproduction import matplotlib.pyplot as plt
import numpy as np
import math
from scipy import ndimage
Nx=2048
Ny=2048
gw=4
x = np.arange(Nx)
y = np.arange(Ny)
X, Y = np.meshgrid(x, y)
a = np.exp(-(X-Nx//2+(-Y+Ny//2)*4)**2/gw**2)
fig = plt.figure()
i=1
for intp in ['none', 'nearest', 'bicubic']:
ax = fig.add_subplot(2,2,i)
ax.imshow(a,origin='lower', aspect='auto',cmap='jet',interpolation=intp)
i+=1
b = ndimage.zoom(a,1.0/math.pi**2,order=0)
ax = fig.add_subplot(2, 2, i)
ax.imshow(b, origin='lower', aspect='auto', cmap='jet', interpolation='none')
plt.show() |
https://matplotlib.org/devdocs/gallery/images_contours_and_fields/image_antialiasing.html Basically if you sub-sample you should smooth first so you don’t get aliasing of small scales into large scales. |
Ok, I hope I understand: When downsampling, the original is smoothed first (antialiased?), then downsampled. It means, that any of the interpolations are then actually not used, but indicate, that the smoothing should be done? Only for 'none' and 'nearest' there is no smoothing before the downsampling. Thats why, I was confused. I think I have seens an intermediate parameter named "antialiased" in one of the posted discussions, but it did not make it to a release ... |
If you downsample the “interpolation” operation is still applied to get the downsampled points. This acts as a smoothing unless you choose nearest. But nearest is a terrible way to down sample a signal because it causes moire patterns. The “antialiased” method applies the smoothing (Hanning) if downsampling or resembling within a factor of two and no interpolation if not. I’m not at my computer so can’t check what version that will be released in. Maybe 3.3 |
How are you diagnosing "blur"? If I set the dpi of the figure to 100 or so and save as a png, then I get speckles for the subsampled data, and a straight line about one or two pixels wide for the smoothed version. (I've zoomed and screenshotted to see the detail). Thats basically how anti-aliasing works: you smooth at slightly larger scale than your new Nyquist wavelength and then sub-sample. The cost is that the resulting signal is a bit smoothed out. None: |
I think this clarifies it, thank you very much. Saving it to a png helped, it might be that the original screenshot was an overlay of bicubic downsampling and the windows screen zoom settings. |
Right it’s confusing to try and figure these things out when the number of pixels In the image changes when you zoom. |
When a huge array (here 8k x 1k) with "sharp" data is displayed with imshow in a window with lower pixel resolution than that array, it looks blurred.
I'm questioning that this behaviour is right. Here is an example of the matplotlib imshow, with a standard line of code
Code for reproduction
Actual outcome
However, the downsampled version (plotted without matplotlib via direct draw and actually using a bicubic algorithm for downsizing) shows the sharp lines I expected.
Expected outcome
So is matplotlib downsampling more than the display resolution and then interpolating back via bicubic interpolation? Or how can one get a blurred output, if the input array is much larger and is "sharp"?
Do not misunderstand, I'm not interested in "nearest" etc.
Unfortunately, the examples with imshow/bicubic only show interpolation while upsampling.
Thank you,
Tom
Matplotlib version
installed Anaconda and packages via conda in a separated env.
The text was updated successfully, but these errors were encountered: