matlab: how to plot multidimensional array

Myx picture Myx · Oct 19, 2010 · Viewed 12.3k times · Source

Let's say I have 9 MxN black and white images that are in some way related to one another (i.e. time lapse of some event). What is a way that I can display all of these images on one surface plot?

Assume the MxN matrices only contain 0's and 1's. Assume the images simply contain white lines on a black background (i.e. pixel value == 1 if that pixel is part of a line, 0 otherwise). Assume images are ordered in such a way as to suggest movement progression of line(s) in subsequent images. I want to be able to see a "side-view" (or volumetric representation) of these images which will show the surface that a particular line "carves out" in its movement across the images.

Coding is done in MATLAB. I have looked at plot (but it only does 2D plots) and surf, which does 3D plots but doesn't work for my MxNx9 matrix of images. I have also tried to experiment with contourslice, but not sure what parameters to pass it.

Thanks!

Mariya

Answer

Andrew Janke picture Andrew Janke · Oct 19, 2010

Are these images black and white with simple features on a "blank" field, or greyscale, with more dense information?

I can see a couple of approaches.

You can use movie() to display a sequence of images as an animation.

For a static view of sparse, simple data, you could plot each image as a separate layer in a single figure, giving each layer a different color for the foreground, and using AlphaData to make the background transparent so all the steps in the sequenc show through. The gradient of colors corresponds to position in the image sequence. Here's an example.

function plotImageSequence

% Made-up test data
nLayers = 9;
x = zeros(100,100,nLayers);
for i = 1:nLayers
    x(20+(3*i),:,i) = 1;
end

% Plot each image as a "layer", indicated by color
figure;
hold on;
for i = 1:nLayers
    layerData = x(:,:,i);
    alphaMask = layerData == 1;
    layerData(logical(layerData)) = i; % So each layer gets its own color
    image('CData',layerData,...
        'AlphaData',alphaMask,...
        'CDataMapping','scaled');
end
hold off

Directly showing the path of movement a "line" carves out is hard with raster data, because Matlab won't know which "moved" pixels in two subsequent images are associated with each other. Don't suppose you have underlying vector data for the geometric features in the images? Plot3() might allow you to show their movement, with time as the z axis. Or you could use the regular plot() and some manual fiddling to plot the paths of all the control points or vertexes in the geometric features.


EDIT: Here's a variation that uses patch() to draw each pixel as a little polygon floating in space at the Z level of its index in the image sequence. I think this will look more like the "surface" style plots you are asking for. You could fiddle with the FaceAlpha property to make dense plots more legible.

function plotImageSequencePatch

% Made-up test data
nLayers = 6;
sz = [50 50];
img = zeros(sz(1),sz(2),nLayers);
for i = 1:nLayers
    img(20+(3*i),:,i) = 1;
end

% Plot each image as a "layer", indicated by color
% With each "pixel" as a separate patch
figure;
set(gca, 'XLim', [0 sz(1)]);
set(gca, 'YLim', [0 sz(2)]);
hold on;
for i = 1:nLayers
    layerData = img(:,:,i);
    [x,y] = find(layerData);  % X,Y of all pixels
    % Reshape in to patch outline
    x = x';
    y = y';
    patch_x = [x; x+1; x+1; x];
    patch_y = [y; y; y+1; y+1];
    patch_z = repmat(i, size(patch_x));

    patch(patch_x, patch_y, patch_z, i);
end
hold off