Search code examples
matlabplotmatlab-figuresubplotlogarithm

Why does MATLAB produce inconsistent Y-axes when generating multiple subplots?


I recently stumbled upon some weird behavior when trying to generate several subplots with a logarithmic y-scale. The subplots are constructed in a loop so that each subplot is generated exactly the same way, still, the Y-scale differs between the various subplots even though they all have the same limits and tick definition, which does not make any sense to me. How can I make sure that the Y-scale and ticks are equal in all subplots? Below is an example that illustrates the problem (MATLAB R2019a).

figure;
    for i=1:9
        ax = subplot(3,3,i);
        plot(rand(5));
        yticks([0:0.2:1]);
        ylim([0, 1]);
       set(ax, "YScale", "log");
    end

Output:

Inconsistent y-scale


Solution

  • You're setting the lower ylim() to zero, which is undefined for logarithmic axis. I presume there's some internal magic of resetting limits when incompatible with the chosen axis representation. Probably MATLAB internally figures out that the lower limit doesn't work, and resets it to automatic before plotting. This is evidenced by the fact that all your plots have a lower limit on exactly the lowest data point in said plot, i.e. using MATLAB's default lower limit of min(data(:)).

    When using 0.001, or any other non-zero positive number, as axis limit it does work:

    figure;
    for ii=1:9 % don't use i
        ax = subplot(3,3,ii);
        plot(rand(5));
        yticks(0:0.2:1); % square brackets are superfluous
        ylim([1e-3, 1]); % Lower limit to 0.001, not 0
        % set(ax, "YScale", "log");
        ax.YScale = 'log';  % Object oriented handling of properties is preferred nowadays
    end
    

    enter image description here


    Side notes:

    • I'd recommend against using i and j as variables as they denote the imaginary unit and can lead to hard to debug errors.

    • Square brackets when creating an array using colon syntax, such as in your yticks(), are unnecessary. When creating an array by listing comma/space separated values, such as in ylim([]) it is necessary to use square brackets.

    • Figure/line/axis handles are nowadays object oriented in style and can be set using the dot-indexing, similar to structures. This can simplify your code by omitting set and get arguments.