Convert milliseconds into hours and plot

datetime-conversion, matlab, plot, time-series

Solution

In this scenario it is preferable to work with `datenum` values and then use `datetick` to set the format of the tick labels of your `plot` to `'HH:MM'`.

Let's suppose that you started taking measurements at `t_1 = [HH_1, MM_1]` and stopped taking measurements at `t_2 = [HH_2, MM_2]`.

A cool trick to generate the array of `datenum` values is to use the following expression:

time_datenums = HH_1/24 + MM_1/1440 : 1/1440 : HH_2/24 + MM_2/1440;

Explanation:

We are creating a regularly-spaced vector `time_datenums = A:B:C` using the `colon (:) operator`, where `A` is the starting `datenum` value, `B` is the increment between `datenum` values and `C` is the ending `datenum` value.

Since your measurements have been taken every minute (60000 milliseconds), then the increment between `datenum` values should be of 1 minute too. As a day has 24 hours, that makes 1440 minutes a day, so use `B = 1/1440` as the increment between vector elements, to get 1 minute increments.

For `A` and `C` we simply need to divide the hour digits by 24 and the minute digits by 1440 and sum them up like this:

- `A = HH_1/24 + MM_1/1440`

- `C = HH_2/24 + MM_2/1440`

So for example, if `t_1 = [08, 00]`, then `A = 08/24 + 00/1440`. As simple as that.

Notice that this procedure doesn't use the `datenum` function at all, and still, it manages to generate a valid array of `datenum` values only taking into consideration the time of the `datenum`, without needing to bother about the date of the `datenum`. You can learn more about this here and here.

Going back to your original problem, let's have a look at the code:

time_millisec = 0:60000:9e6;             % Time array in milliseconds.
power = 10*rand(size(time_millisec));    % Random power data.

% Elapsed time in milliseconds.
elapsed_millisec = time_millisec(end) - time_millisec(1); 
% Integer part of elapsed hours.
elapsed_hours_int = fix(elapsed_millisec/(1000*60*60));
% Fractional part of elapsed hours.
elapsed_hours_frac = (elapsed_millisec/(1000*60*60)) - elapsed_hours_int;

t_1 = [08, 00]; % Start time 08:00
t_2 = [t_1(1) + elapsed_hours_int, t_1(2) + elapsed_hours_frac*60]; % Compute End time.

HH_1 = t_1(1); % Hour digits of t_1
MM_1 = t_1(2); % Minute digits of t_1

HH_2 = t_2(1); % Hour digits of t_2
MM_2 = t_2(2); % Minute digits of t_2

time_datenums = HH_1/24+MM_1/1440:1/1440:HH_2/24+MM_2/1440; % Array of datenums.

plot(time_datenums, power);    % Plot data.
datetick('x', 'HH:MM');        % Set 'HH:MM' datetick format for the x axis.

This is the output:

Problem

I'm trying to convert an array of milliseconds and its respective data. However I want to do so in hours and minutes. ``` Millis = [60000 120000 180000 240000....] Power = [ 12 14 12 13 14 ...] ``` I've set it up so the data records every minute, hence the 60000 `millis` (= 1 minimte). I am trying to plot time on the `x` axis and power on the `y`. I would like to have the `x` axis displayed in hours and minutes with each respective power data corresponding to its respective time. I've tried this ``` for i=2:length(Millis) Conv2Min(i) = Millis(i) / 60000; Time(i) = startTime + Conv2Min(i); if (Time(i-1) > Time(i) + 60) Time(i) + 100; end end s = num2str(Time); ``` This in attempt to turn the milliseconds into hours starting at 08:00 and once 60 minutes have past going to 09:00, the problem is plotting this. I get a gap between 08:59 and 09:00. I also cannot maintain the `0=initial 0`.

Original source