Convert x-axis values to datetime

31 次查看(过去 30 天)
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 个评论
Peter Perkins
Peter Perkins 2018-4-19
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.

请先登录,再进行评论。

采纳的回答

Walter Roberson
Walter Roberson 2018-4-19

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 个评论
Tim
Tim 2018-4-20
编辑:Tim 2018-4-20

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 2018-4-20

You can probably replace pause with drawnow.

请先登录,再进行评论。

更多回答(2 个)

David Stauffer
David Stauffer 2020-10-27
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;

Benjamin Kraus
Benjamin Kraus 2018-4-19
编辑:Benjamin Kraus 2018-4-19

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 个评论
Walter Roberson
Walter Roberson 2018-4-19
(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 2018-4-20
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.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Data Exploration 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by