MATLAB: Is the plot of ‘imagesc’ flipped if ‘hold on’ is executed first

flippedholdimagescMATLABplot

I have a matrix 'C' and I want to display the data in 'C' as an image with scaled colors by using 'imagesc'.
However, I get two different plots whether I use 'hold on' before or after 'imagesc', as per the two following examples.
  • Example 1
>> figure
>> imagesc( C )
>> hold on
  • Example 2
>> figure
>> hold on
>> imagesc( C )
In Example 2, the image is flipped and inset so that it does not fill up the entire figure size. In Example 1, instead, it plots normally.
Why is MATLAB behaving differently when I use 'hold on' first?

Best Answer

From the MATLAB documentation for 'hold' ( https://www.mathworks.com/help/matlab/ref/hold.html ):
'hold on' retains plots in the current axes so that new plots added to the axes do not delete existing plots. New plots use the next colors and line styles based on the ColorOrder and LineStyleOrder properties of the axes. MATLAB adjusts axes limits, tick marks, and tick labels to display the full range of data. If axes do not exist, then the 'hold' command creates them.
From the MATLAB documentation for 'imagesc' ( https://www.mathworks.com/help/matlab/ref/imagesc.html ):
'imagesc(C)' displays the data in array 'C' as an image that uses the full range of colors in the colormap. Each element of 'C' specifies the color for 1 pixel of the image. The resulting image is an m-by-n grid of pixels where m is the number of columns and n is the number of rows in 'C'. The row and column indices of the elements determine the centers of the corresponding pixels.
In Example 1, 'imagesc' creates an axes object with a 'size ( C )' grid of pixels. According to the description given in the documentation above, the first pixel is centered in [ 1 , 1 ] and the last pixel is centered in [ size(C, 1) , size(C, 2) ]. Being the dimension of each pixel equal to one, the x axis limits are [ 0.5 , size(C, 1) + 0.5 ]. The same happens for the y axis.
Moreover, by default, since you use 'imagesc' without 'CData' as an input argument, then you are using the high-level version of 'imagesc'. One of the features of the high-level version is that the property 'YDir' of the axes object is set to 'reverse'. That is, the values along the y-axis increase from top to bottom. More information about this can be found on the MATLAB documentation for 'imagesc'.
In Example 2, instead, the axes object is first created by the call of 'hold on', which creates an axes object with the following characteristics (among the others):
- XLim = YLim = [ 0 , 1 ]
- YDir = 'normal'
When 'imagesc' plots on the previously-created axes object, it is not able to change the 'YDir' property of the object. Thus the image is flipped with respect to the previous case. A similar behavior occurs for the axis limit, which are automatically adjusted by MATLAB by integer steps.
The quickest way is to use 'hold on' after 'imagesc' so that the properties of the axes object generated by the latter are kept.
If you want to execute 'hold on' first, you can modify the axes parameters after the 'hold on', as follows:
>> figure
>> ax = gca;
>> hold on
>> ax.XLim = [ 0.5, size(C, 1) + 0.5 ];
>> ax.YLim = [ 0.5, size(C, 2) + 0.5 ];
>> ax.YDir = 'reverse';
>> imagesc( C )