Search code examples
octaveoctave-gui

Plot with dates goes wrong


I run into this problem: when I plot in Octave without x values, it's ok. when I add x values (which are supposed to be dates, but I don't impose the date format), it goes weird

ab = rand(96,1);
close all
figure
plot(ab)

Gives this figure:

plot without x values

close all
figure
plot(datenum('01-Nov-2020 00:00','dd-mmm-yyyy HH:MM'):1/24/4:datenum('01-Nov-2020 23:45','dd-mmm-yyyy HH:MM'),ab)

Gives this figure: plot with x values As you can see, the x values are all within 1 day, so I don't even know why the x tick show more than 1 day...

Anyone would have a smart explanation?


Solution

  • EDIT: As Tasos stated in an earlier answer, it's a "problem of OpenGL being unable to deal with the precision involved when adding small numbers to a large number".


    From my point of view, that's "just" an Octave bug, MATLAB (tested with MATLAB Online) doesn't show that behaviour. It seems, Octave has problems with small x intervals when the actual x value is relatively high, cf.

    subplot(2, 1, 1);
    x = linspace(800000, 800000 + 2*pi, 100);
    y = sin(x);
    plot(x, y);
    
    subplot(2, 1, 2);
    x = linspace(0, 2*pi, 100);
    y = sin(x);
    plot(x, y);
    

    The corresponding output is:

    Output sine

    It seems, some x values are getting "merged"!? I haven't searched in depth for reported bugs on that issue...

    But, to work around that issue in your case, you could try plotting the data starting at 0, and later just adapt the xticklabels:

    % Data
    ab = rand(96, 1);
    
    figure(1);
    
    % Plot without dates
    subplot(3, 1, 1);
    plot(ab);
    xlim([1, 96]);
    
    % Plot with dates (standard, faulty)
    subplot(3, 1, 2);
    dates = linspace(datenum('01-Nov-2020 00:00', 'dd-mmm-yyyy HH:MM'), 
                     datenum('01-Nov-2020 23:45', 'dd-mmm-yyyy HH:MM'), 
                     size(ab, 1))
    plot(dates, ab);
    datetick('x', 'dd-mm-yyyy HH:MM');
    xlim([dates(1), dates(end)]);
    
    % Plot with dates (custom, correct)
    subplot(3, 1, 3);
    # For plotting, subtract start date
    dates_for_plot = dates - datenum('01-Nov-2020 00:00', 'dd-mmm-yyyy HH:MM')
    plot(dates_for_plot, ab);
    datetick('x', 'dd-mm-yyyy HH:MM');
    # Add custom xticklabels with re-added start date
    xlim([dates_for_plot(1), dates_for_plot(end)]);
    xticklabels(cellstr(datestr(xticks + datenum('01-Nov-2020 00:00', 
                                                 'dd-mmm-yyyy HH:MM'))));
    

    That'd be the output:

    Output data