Search code examples
matlabplotmatlab-figure

Matlab plot with partly exponential or logarithmic scale depending on the y values


I want to make a simple plot in Matlab, of, say

% data:
x = -9:8;
% dates:
Y = [];
for year = 2008:2016
    Y = vertcat(Y,[year;year]);
end
M = repmat([01;06],9,1);
D = [01];
vector = datetime(Y,M,D);

plot(vector, x);
dateaxis('x', 12);

Now I want either a logarithmic scale for all values of x

x<0

or an exponential scale for

x>0

but a normal scale for the other part of the plot. The reason is that the negative values go so low down that with a normal scale the positive values appear to be all zero. I looked at the help but the semilog functions etc. don't help me. Any suggestions?


Solution

  • You could create two subplots and but them together

    % plotting
    figure;
    p1 = subplot(2,1,1);
    idx = x>=0; plot(vector(idx), x(idx));
    p2 = subplot(2,1,2);
    idx = x<=0; plot(vector(idx), x(idx));
    % Make x-axis limits the same (must use datenum)
    lims = datenum([min(vector), max(vector)]);
    xlim(p1, lims); xlim(p2, lims);
    % Make the plots meet in the middle
    h = 0.45; w = 0.9; % height and width
    set(p1, 'position', [(1-w)/2, 0.5, w, h])
    set(p2, 'position', [(1-w)/2, 0.5-h, w, h])
    % Ensure the y axes meet at 0
    ylim(p1, [0, max(x)]); ylim(p2, [min(x), 0]);
    

    The two individual plots can be done however you like. So if you'd plotted them with the relevant methods you would get one with an exponential y-axis and one with a log y-axis.

    Instead of the plot(...) lines above, you could use

    % log y plot
    semilogy(datenum(vector(idx)), x(idx))
    

    Note that the output of this works exactly as expected, but the actual plot you're trying to do sounds very confusing. It would probably be better in most situations to present this as two separate plots if the axes really do want to be different. In which case, use the code above without the position lines!


    Before messing around with the plot types, this is what the output looks like, the y-axes above and below the 0 line are completely independent, since this is actually 2 plots:

    plot