Precreated axes with datetime ruler and time zones

22 views (last 30 days)
I would like to precreate an axes with a datetime XAxis ruler and then drop in lines with datetime objects for the 'xdata'. Everything works great until I give the line input time data a timezone. If I say the data is in 'UTC' time, I get an error:
'Cannot combine or compare a datetime array wit a time zone with one without a time zone.'
I'm guessing this in the guts of the XAxis ruler in which there are three parameters that appear to be datetime oriented. I tried to set all 3 of those parameters with the set function to datetime objects that have a time zone ('local'). But I still get the above error when attempting to add a line.
I have tried to manually set all the datetime parameters to datetime objects with no success.
How to I precreate an axes with the correct XAxis ruler to handle my datetime data that has a time zone? I think I will have to actually call the plot function to plot a line instead of calling the line function ... at least once.
% Trying to get this to work ...
% This works:
dtr = matlab.graphics.axis.decorator.DatetimeRuler;
ax = subplot(2,1,1,...
'XAxis',dtr);
drawnow % not sure why I need this ...
xdata = [datetime('yesterday'),datetime('now')]; % data does not have a time zone
line('parent',ax,'xdata',xdata,'ydata',1:2);
% This doesn't
dtr = matlab.graphics.axis.decorator.DatetimeRuler;
ax = subplot(2,1,1,...
'XAxis',dtr);
drawnow % not sure why I need this ...
xdata = [datetime('yesterday'),datetime('now')];
xdata.TimeZone = 'UTC'; % giving my data a time zone ...
line('parent',ax,'xdata',xdata,'ydata',1:2);
dtr = matlab.graphics.axis.decorator.DatetimeRuler;
ax = subplot(2,1,1,...
'XAxis',dtr);
get(dtr)
dtr.Limits.TimeZone
L = dtr.Limits
L.TimeZone = 'local'
L.TimeZone
mtv = dtr.MinorTickValues;
mtv.TimeZone = 'local'
mtv.TimeZone
tv = dtr.TickValues;
tv.TimeZone = 'local
tv.TimeZone = 'local'
set(dtr,'Limits',L,'MinorTickValues',mtv,'TickValues',tv)
set(dtr,'MinorTickValues',mtv,'TickValues',tv','Limits',L)
set(dtr,'TickValues',tv','MinorTickValues',mtv,'Limits',L)
dtr
ax
set(ax,'XTick',tv,'XLim',L)
% I'm going to have to hack it like this ... will have to realize the subplot capability myself
xdata = [datetime('yesterday'),datetime('now')];
xdata.TimeZone = 'local'
o = plot(xdata,1:2)
ax = gca;
xdata.TimeZone = 'UTC';
delete(o)
line('parent',ax,'xdata',xdata,'ydata',1:2);
  1 Comment
dpb
dpb on 12 Sep 2019
Probably worth a bug report for "quality of implementation" issue if not outright bug. Not surprising to me there are still warts in the relatively new datetime ruler object...it's not been around very long and is pretty complex.
One thing you can do is use NaN for the plotted "data" in the superfluous line so it won't ever actually be displayed--but will create the line handle.
Sometimes for such purposes I'll go ahead and deliberately pre-create the line handle(s) intending to later populate with real X/YData arrays and so having them already there may be a bonus rather than a detriment if reconsider how you're creating the end result just slightly.

Sign in to comment.

Accepted Answer

Benjamin Kraus
Benjamin Kraus on 17 Mar 2023
Edited: Benjamin Kraus on 17 Mar 2023
I believe the issue you are facing is that the XAxis has a specific time zone that is initialized when you first call any plotting commands (like line). Technically, the DatetimeRuler has a "reference date" which is used to both determine the internal conversion between double and datetime and dictate the TimeZone of the ruler. This reference date also impacts tick picking (the DatetimeRuler will select ticks that fall on nice boundaries in the specified time zone).
By default, the reference date and time zone is determined from the data that is used when the XAxis is first initialized (via the plotting command). Anything you plot into that axes afteward will display using that reference date and time zone, and this time zone is the time zone that is used by all user-facing properties on the DatetimeRuler (like Limits and TickValues).
Prior to R2023a, there was no way to access the internal reference date, although you could figure it out by calling num2ruler(0, axis). There was also no way to change the internal reference date or time zone without clearing your axes and starting over.
Starting in MATLAB R2023a, you can now directly query the ReferenceDate, and you can update the time zone of the x-axis of existing plots by setting the ReferenceDate on the ruler.
You can read about this on the DatetimeRuler Properties doc page.
For example:
d = datetime(2023,2,10,12,0,0,TimeZone='America/New_York') + minutes(0:60);
% When you call plot, the axes will be configured to use the
% "America/New_York" time zone.
plot(d,sin(1:numel(d)));
% Prior to R2023a, you could indirectly query the ReferenceDate like this:
ax = gca;
num2ruler(0,ax.XAxis)
ans = datetime
10-Feb-2023 00:00:00
% Starting in R2023a, you can query the current reference date and time zone like this:
ax.XAxis.ReferenceDate
ans = datetime
10-Feb-2023 00:00:00
ax.XAxis.ReferenceDate.TimeZone
ans = 'America/New_York'
% Prior to R2023a, the only way to change the reference date was to clear
% your axes and plot again.
% Starting in R2023a, you can change the reference date and time zone by setting the ReferenceDate on the XAxis.
ax.XAxis.ReferenceDate = datetime(2023,2,10,'TimeZone','Europe/London');

More Answers (1)

Dan
Dan on 12 Sep 2019
Thanks for the feedback ... will try to write a bug report soon.
I just wanted to make a comment on how thrilled I am with the datetime ruler. WIth my hack, I was able to specify that the data going into the datetime object was 'UTC' but my axes was set to 'local' time which allowed me to see the data referenced to local time in the figure. Great to have reduced the headaches associated with dates and time. We also have to get them to display the object to higher precision ... the object supports much higher precision but won't display to that precision and I can't force it to do so ... I have to do some rounding and differencing to see what I want to see. (duration object rules here).

Categories

Find more on Data Distribution Plots in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!