Display image with nonlinearly spaced axis.
UIMAGE(X,Y,C) displays matrix C as an image, using the vectors X and Y to specify the X and Y coordinates. X and Y may be unevenly spaced vectors, but must be increasing. The size of C must be LENGTH(Y)*LENGTH(X). (Most probably you'll want to display C' instead of C).
Contrary to Matlab's original IMAGE function, here the vectors X and Y do not need to be linearly spaced. Whereas Matlab's IMAGE function linearly interpolates the Xaxis between X(1) and X(end), ignoring all other values (idem for Y), here UIMAGE allows for X and/or Y to be unevenly spaced vectors, by locally stretching the matrix C (ie, by duplicating some elements of C) for larger X and/or Y intervals.
Use UIMAGESC to scale the data using the full colormap. The syntax for UIMAGESC(X,Y,C,...) is the same as IMAGESC(X,Y,C,...).
Typical uses:
 Plotting a spatiotemporal diagram (T,X), with unevenly spaced time intervals for T (eg, when some values are missing, or when using a nonconstant sampling rate).
 Plotting a set of power spectra with frequency in logscale.
Example:
c = randn(50,20); % Random 50x20 matrix
x = logspace(1,3,50); % logspaced Xaxis, between 10 and 1000
y = linspace(3,8,20); % linspaced Yaxis, between 3 and 8
uimagesc(x,y,c'); % displays the matrix
1.1  Bug fixed when both X and Y axis are not linearly spaced (thank you Janti and Tim!!) 

help text improved 
lior michaeli (view profile)
Michelle Zhang (view profile)
THIS IS AMAZING!
Giacomo (view profile)
Thank you very much
Teresa Madsen (view profile)
It's generating an easily fixable warning in the latest version of Matlab:
Warning: NARGCHK will be removed in a future release. Use NARGINCHK or NARGOUTCHK instead.
> In uimage
The first line of code in the function is currently:
error(nargchk(3,inf,nargin));
...which can be replaced by:
narginchk(3,inf);
Aaron (view profile)
Works great.
Francesco (view profile)
I suggest the following improvement: in the uimage.m file, when both X an Y are uneven, it is better to replace
for i=1:nx
for j=1:ny
indi = find(x<=xe(i));
indj = find(y<=ye(j));
ce(j,i) = c(indj(end), indi(end));
end
end
with
xi = zeros(nx,1);
yi = zeros(ny,1);
for i=1:nx
indi=find(x<=xe(i));
xi(i)=indi(end);
end
for j=1:ny
indj=find(y<=ye(j));
yi(j)=indj(end);
end
for i=1:nx
for j=1:ny
ce(j,i) = c(yi(j), xi(i));
end
end
Kind regards.
Peter Pablo (view profile)
Dear Matt,
thank you for your suggestion. In order to remove the necessity of functions 'row' and 'col', the line 'ce = ...' should read:
ce = interp2(x,y,c,xe(:),ye(:)','nearest');
I can confirm that the speed for plot creation is increased by a factor of almost 500!!
(Tested using MATLAB 2014a)
Matt Raum (view profile)
Output is different from imagesc for nominally identical inputs.
sz=21;
noise=1e6;
x=linspace(0,1,sz)+noise*randn(1,sz);
y=linspace(0,1,sz)+noise*randn(1,sz);
z=randn(sz);
figure;
imagesc(x,y,z);hline(y,'k');vline(x,'k');
figure;
uimagesc(x,y,z);hline(y,'k');vline(x,'k');
I was able to correct this and speed up the code significantly by using the following replacement for the general (~evenx && ~eveny) case:
nx = round(1 + (x(end)  x(1))/dx);
nx = min(nx, nmax);
xe = linspace(x(1), x(end), nx);
ny = round(1 + (y(end)  y(1))/dy);
ny = min(ny, nmax);
ye = linspace(y(1), y(end), ny);
ce = interp2(x,y,c,col(xe),row(ye),'nearest');
The functions 'col' and 'row' just turn one dimensional vectors into column and row vectors, respectively. A similar loop eliminating modification made to the other two cases will presumably speed them up as well.
Thanks Frederic!
Anders (view profile)
perfect!
Gustaf Lönn (view profile)
Very nice script! When using large matrices, panning and zooming is *much* faster with this script than with pcolor.
Natan (view profile)
very nice work, should be part of Matlab in my view...
Sven (view profile)
Secondly, imagine this scenario:
You have a volume of images, and you want to scroll through those images, viewing each one. If they were monotonically spaced, you could just call h=image(X,Y,C(:,:,1)) on the first slice, then call set(h,'CData',C(:,:,i)) on the rest of the slices.
When they are NOT monotonically spaced, you now need to call h=uimage(X,Y,C(:,:,1)). The problem here is that the 'CData' has a new number of rows/columns, so for subsequent images you can't just update 'CData' like you could before.
Instead, consider if uimage also gave the *indices* it used to resample C monotonically. Now on the first image you could call:
[h,Xinds,Yinds]=uimage(X,Y,C(:,:,1))
and on subsequent calls you could now use:
set(h,'CData',C(Yinds,Xinds,i))
This would save recalculating the resampling locations for each separate slice (since they are all the same), and it would also save deleting and recreating image handles for each slice you want to show.
Frederic, I've just sent you an overhaul of your code that does just this (and includes the speedup from my above comment).
Sven (view profile)
There are a few places where big speed gains can be made. Firstly, the interpolation step can be improved by removing a loop near line 88:
tic % Original version
for j=1:ny
indj = find(y<=ye(j));
ce(j,1:nx) = c(indj(end), 1:nx);
end
toc
tic % Faster version
T = bsxfun(@minus, ye(:), y(:)')>=0;
% Following two lines can be replaced with FIND_NDIM: indsJ = find_ndim(T,2,'last');
[~, indsJ] = max(flipdim(T,2),[],2);
indsJ = length(y)+1  indsJ;
ce2 = c(indsJ,:);
toc
isequal(ce, ce2)
Elapsed time is 0.013454 seconds.
Elapsed time is 0.001384 seconds.
ans =
1
So here we get a 13x speedup (and the sped up version gives identical output to the original)
Oliver Woodford (view profile)
pcolor creates patch objects, which can create problems when exporting using the painters renderer. This method allows images with nonlinear axes to be rendered as images, which export much better.
Oliver Woodford (view profile)
Rob Campbell (view profile)
It's still a good idea. It's just a redundant good idea ;)
Frederic Moisy (view profile)
Oooooooh... I must admit that Bjorn Gustavsson is totally right. This submission actually mimick to behavior of pcolor. Thank you for your remark, and sorry for this false good idea...
F.
Bjorn Gustavsson (view profile)
Just a question: What improved features does this provide compared to simply calling:
pcolor(x,y,c),shading flat,axis ij
Tim (view profile)
I just debugged an error similar to that of Janti.... I think the i,j indexing is wrong in line 122. See below..
% ce(j,i) = c(indi(end), indj(end)); % original version
ce(j,i) = c(indj(end), indi(end)); % "corrected" version
Janti (view profile)
If you need to have both axis in logspace you get an error.
please add the following in the for loop in uimage.m line:120
indi = find(x<=xe(i));
indi = min(indi,length(y));
indj = find(y<=ye(j));
indj = min(indj,length(x));
ce(j,i) = c(indi(end), indj(end));
Thanks for this m file!
JonFredrik Hopperstad (view profile)
Excellent work. This was exactly what I was looking for. I just did 15 queryreplace for 'imagesc' in my code and it works beautifully. Thanks!
Gabriel Akira Schreiber (view profile)
Oh soo cool! Just what I needed.Very nicely done.
Thanks Frederic. Clever trick , works perfectly!
Excellent work. Piggybacks neatly on core matlab image() and imagesc() functions so I can simply replace these calls. If my input is in fact perfectly linear, then these calls are used directly without further processing. Thank you.
BEautifull idea!