Convert x-axis values to datetime

63 visualizzazioni (ultimi 30 giorni)
Tim
Tim il 18 Apr 2018
Commentato: Walter Roberson il 27 Ott 2020
How can I convert numeric x-axis values to datetime values? I have a plot with time in seconds (from a specific epoch) and I'd like to convert the values to datetime values. I know that plot can take datetime in the initial input, but if that is not an option, can I convert the axis from a NumericRuler to a DatetimeRuler after the plot has been generated?
  1 Commento
Peter Perkins
Peter Perkins il 19 Apr 2018
Best of my knowledge you cannot do that. Closest would be to convert the datetimes to numbers (datenums? posixtimes?) and specify ticks and tick labels explicitly.

Accedi per commentare.

Risposta accettata

Walter Roberson
Walter Roberson il 19 Apr 2018

If you have an existing plot with datetime axes, then you can set the XRuler of the second plot to be the XRuler of the first plot:

ax2.XRuler = ax1.XRuler

In my test in R2018a, the X axis display disappears from the old location and appeared in the new location, but with changed limits and changed tick locations reflecting the different span of XData that I had for the two. Changing the properties in the old axis changed the properties in the new axis as well, but the display updates were still only for the new location. Thus the XRuler object itself has its handle copied, but the display system is only prepared for an XRuler to be displayed in one place at a time (only one Parent, I guess.)

  2 Commenti
Tim
Tim il 20 Apr 2018
Modificato: Tim il 20 Apr 2018

This appears to work so far for me, with a small caveat... I have to pause execution for a second, otherwise, I get an error when changing the xdata from numeric to datetime values. Must be a delay before the objecct conversion is complete??? Maybe a waitfor would work instead of pause? But I couldn't identify the a handle/object that worked. line.Parent.XRuler and axdt.XRuler aren't it...

Update:

waitfor(line.Parent.XAxis,'TickLabelFormat') works

Details:

% get time data from xdata property
t = get(line,'xdata');
% convert to datetime
dt = datetime(1980,1,6,0,0,0) + seconds(t);
% create a temporary new axes with a DatetimeRuler
axdt = axes;
plot(NaT,NaN);
% replace the original NumericRuler
line.Parent.XRuler = axdt.XRuler;
% Set the xdata values
% *** Have to wait before doing this!!??? ***
% if I don't wait, the set line fails becasue dt is not numeric!!!
waitfor(line.Parent.XAxis,'TickLabelFormat')
set(line,'xdata',dt);  
% Delete the temporary axes
delete(axdt);
Benjamin Kraus
Benjamin Kraus il 20 Apr 2018

You can probably replace pause with drawnow.

Accedi per commentare.

Più risposte (2)

David Stauffer
David Stauffer il 27 Ott 2020
I recently ran into similar issues. It looks like you can convert the XAxis type to an instance of the DatetimeRuler class and then update the XData values as appropriate. (I'm using R2019B)
% Data
time_sec = 0:30;
date_zero = datetime(2020, 10, 27, 12, 0, 0);
time_date = date_zero + seconds(time_sec);
data = sin(linspace(0, 2*pi, length(time_sec)));
% Plot
fig = figure;
ax = axes(fig);
plot(ax, time_sec, data, '.-');
% convert axes to datetime
set(ax, 'XAxis', matlab.graphics.axis.decorator.DatetimeRuler);
% update values to appropriate datetime equivalents
drawnow(); % <-- as in other answer, seems necessary to give the plot time to update
ax.Children.XData = time_date;
  1 Commento
Walter Roberson
Walter Roberson il 27 Ott 2020
ah, this is the same theory as I used but much cleaner coding!

Accedi per commentare.


Benjamin Kraus
Benjamin Kraus il 19 Apr 2018
Modificato: Benjamin Kraus il 19 Apr 2018

There is no documented way to directly change the ruler type, but you can do it by plotting NaT (not a time), for example:

ax = axes;
p = plot(NaT,NaN);
delete(p);

Note that most plotting commands will reset the axes, so if you want to add things to the axes created in my example you will likely need to turn on hold. In addition, this will only work if the axes is empty. If hold is on, and you try to plot a different datatype, you will get an error about incompatible datatypes.

The specifics depend on what you are trying to do and the specific plotting commands. I believe any plotting commands which "understand" datetime (including plot, scatter, etc.) will error if you try plotting using a different datatype while hold is on. However, I believe other commands which are more low-level (and don't directly understand datetime, such as text and patch) will allow you to plot using numeric data into an axes configured for datetime data. In order for this to work, you need to use ruler2num to convert your data into doubles (in most situations, datenum will not do the conversion correctly).

You said it isn't an option to call plot with datetime inputs, why is that? What are you trying to plot? What is your overall goal?

  2 Commenti
Walter Roberson
Walter Roberson il 19 Apr 2018
(Just after posting the above, Benjamin also posted in https://www.mathworks.com/matlabcentral/answers/370074-gca-currentpoint-with-the-datetime-ticks-on-the-x-axis#answer_316069 pointing out the existence of num2ruler() and ruler2num(), which are potentially relevant in this situation.)
Tim
Tim il 20 Apr 2018
Benjamin, I don't understand how to use your answer. I already have axes with data. So, how does creating a new one help? And I can't do plot(NaT, NaN) on my existing axes because of the different data type conflict that you mention.
I was hoping I could change my numeric axis to datetime so as to avoid having to modify several lower level functions that I have for simple data plotting. These lower level functions read and plot data from a file, assuming that the time data is numeric (seconds), specifically, time data is GPS seconds (since 1980 Jan 6 00:00:00). I want to provide the option to display the time axis in several formats, one of which being calendar date and time. It would be much easier if I can do the axis conversion after the data has been plotted to avoid changing other functions. Works fine for other time formats that I'd like, as they simply involve a time offset or modulo and don't change the underlying data type. But can't seem to do this with datetime.

Accedi per commentare.

Categorie

Scopri di più su Dates and Time in Help Center e File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by