Imagesc subsampling hides data -- didn't happen in older Matlab

22 vues (au cours des 30 derniers jours)
James
James le 30 Mar 2023
Our current codebase uses R2009a, and we are in the process of upgrading to R2021a (yes, I know it's not the latest, anyway...)
I create a simple scaled color image like so:
figure;
setwinsize(gcf,1500,300); % defined below
n = 17000; x = zeros(100,n); x(:,1:10:n) = 1;
imagesc(x);
xlim([7000 8000]);
where setwinsize is defined as follows:
function setwinsize(winhandle, x, y)
% setwinsize(winhandle,x,y)
%
% Set the size of a window without moving the top left corner
%
% e.g. setwinsize(gcf,1000,500)
u = get(winhandle,'Units');
set(winhandle,'Units','pixels');
p = get(winhandle,'Position');
top = p(2) + p(4);
p(3) = x;
p(4) = y;
p(2) = top - p(4);
set(winhandle,'Position',p);
set(winhandle,'Units',u);
end
The intent being to resize a figure window according to the desired pixel dimensions. Since I'm doing this on a 1920x1080 monitor, I expect that my monitor's resolution should be sufficient to show every data point in the image when zoomed-in.
When I make the above image and zoom-in the x limit, in R2009a, I see a series of vertical lines every 10th index along the horizontal dimension of the image, which is what I expect to see. If I make the same image and zoom-in identically in R2021a, I instead just see a blank image. If I shrink the x-axis limit enough (roughly xlim([7000 7500])) or grow it enough (roughly xlim([7000 8500])), I can start seeing lines again, which suggests that the image as it is shown on my screen seems to be subsampling the actual grid of data even though I should expect there to be at most one data point represented per pixel on my screen. Even exporting these as .pngs with print does not change this story (nor does saving the R2021a version with the newer exportgraphics function). I know plotting was overhauled in R2014b, so perhaps asking "what changed?" is not a useful question, but I'm at least looking for a way to replicate the previous behavior (that is, to generate an image at a specified resolution with each data point being mapped to a pixel in the output image, without smoothing or subsampling).
Admittedly setwinsize is an ancient thing that we've been dragging and could be the culprit, though it's not immediately clear to me. Any insight is appreciated -- I'm sure there's a better way to do this in the newer version anyhow.
Thanks!
  4 commentaires
Rik
Rik le 31 Mar 2023
I don't expect that function is causing any problem. It seems perfectly serviceable to me.
I suspect changes in the renderer may be causing this. I don't know if it is possible for you to use painters instead.
Both exportgraphics and print use the same renderer as the figure (at least as I understand it), so a problem in one of them will manifest in all of them.
James
James le 4 Avr 2023
Thanks for the suggestion. I can change the renderer (tried switching between opengl, painters, and zbuffer) but all three still have this issue. I can see tiny (order one pixel) changes when I switch renderers, so I think it's properly taking effect, just that it isn't addressing this issue.
I do notice that if I manually do imagesc(x(:,7000:8000));, then I see the lines where I would expect to. It's almost like the downsampling is being computed on the full image and not recomputed when the axes are resized, while it was in R2009a.

Connectez-vous pour commenter.

Réponse acceptée

James
James le 6 Avr 2023
Answering my own question in case anyone else has this issue. I contacted Mathworks support about this, and they were able to reproduce the issue, and are attributing it to a limitation with the software implementation of OpenGL.
Support then pointed me to a "setMaxImageSize" function on the File Exchange which attempts to optimize the image after creation. Using it on an image produced by imagesc then allows it to show the lines where I expect them, even after changing the zoom level:
figure;
n = 17000; x = zeros(100,n); x(:,1:10:n) = 1;
setwinsize(gcf, 1500, 300);
imx = imagesc(x); % have to save handle to a variable explicitly; can't use gcf
xlim([7000 8000]);
% at this point, lines will be hidden just like before
setMaxImageSize(imx, 'interaction');
% now lines show up! Can change xlim arbitrarily and they still will!
A big thank-you to Mathworks' Caesar Rivadeneyra for writing this function and Maddie Moon for finding it/helping me investigate this!

Plus de réponses (0)

Catégories

En savoir plus sur Graphics Object Properties dans Help Center et File Exchange

Produits

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by