How do you make the x-axis in imagesc using datetime values?
43 views (last 30 days)
Show older comments
Hi,
I have data that I wish to display using imagesc with the y-axis being a unit of distance and the x-axis being a datetime array, however, I receive an error when I do this. Any help would be appreciated.
Thanks.
---
For example:
- data : 150 x 1200 x 3 unit8 array of data
- x : 150 x 1 array of distances that correspond to the information in "data"
- t : 1200 x 1 datetime array of times that correspond to the information in "data"
imagesc([t(1) t(end)],[x(1) x(end)],I)
Throws the following error:
Error using image
Image XData and YData must be vectors.
Error in imagesc (line 20)
hh = image(varargin{:},'CDataMapping','scaled');
0 Comments
Accepted Answer
Benjamin Kraus
on 20 Sep 2023
Edited: Benjamin Kraus
on 20 Sep 2023
Starting in MATLAB R2023b, both the image and imagesc commands support datetime and duration data for the XData and YData properties.
nexttile
x = [0 1];
t = datetime(2023,9,20)+hours([0 1]);
imagesc(t,x,peaks);
nexttile
x = [0 1];
t = hours([1 23]);
imagesc(t,x,peaks);
If you are working with a release older than MATLAB R2023b you can use the workaround discussed in this answer.
0 Comments
More Answers (4)
Walter Roberson
on 27 Sep 2017
In the case where the x axis is to be a duration array (rather than a datetime array):
First, plot something using an x axis in the same time units as you want the imagesc to be labeled with.
Then
hold on
h = imagesc(I);
set(h, 'XData', [1, seconds(t(end))]);
Modify the "seoonds" to the appropriate time measure. The purpose of the seconds() there is to strip off the duration class, converting the t values to pure numeric values. image() will treat the numeric values as if they were in the active duration units.
This is, of course, a hack.
If your values are datetime arrays then it appears you can do something similar. It appears that the default XData for the imagesc() will be converted into days, probably relative to the first date (but double check -- it might perhaps be relative to the month of the first date.) You cannot use days() on a datetime array to convert to number of days, but you can do
set(h, 'XData', [1 days(t(end)-t(1))]);
You might need to play with the boundary conditions a little.
7 Comments
Damsel in Distress
on 30 Nov 2018
Hi,
Has the datetime/duration support made it into a released version yet? I am running 2017b and cannot get it to work (perhaps it is user error?!). If not do we know which release this is likely to be fixed in?
Thanks!
Andrew McLean
on 23 Mar 2020
I've tried with Matlab R2019a it doesn't work. Does it work with R2020a, documentation suggests not?
Erik
on 25 Oct 2019
I found a way arround. It is possible to add an image produced by imagesc to an already existing axis with a duration ruler.
Your duration range in the imagesc call should be converted to numeric. As you can see in figure below, the graph keeps the duration ruler for the XAxis. .
In the code, you can find that the order of the image and other axis children (e.g. plotlines) can changed to dept, which effectively set's image below the rest. In 3D plots the order is default dept I presume.
I did not do that but made the image partly transparent to show the dots of the first plot command.
Succes Erik Esveld
function PlotFlirData(FD)
%% Plot FD data
% FD.time aquisition type duration
% FD.date aquisition type datetime
% FD.mean mean temperature vector
% FD.temp vector of temperature bin (from T-0.5 to T+0.5)
% FD.tempfrac isotermal area fraction maxtrix (time,temp)
%
% 2019 erik.esveld@wur.nl
%% Heatmap in time plot
% we use imagesc ( heatmap itself does not work well)
% note that cdata(1,1) is nomally uppper left
% but not when ax.YDir = 'Normal' such as in plot
fi = figure;
fi.Color = 'w';
% because imagesc does not support creation of duration rulers,
% we first use plot with duration as x data and mean value as y data
plot(FD.time,FD.mean,'.k');
hold on;
% give the ranges for the image data
timerange = [FD.time(1) FD.time(end)];
temprange = [FD.temp(1) FD.temp(end)];
fracrange = [0 0.3];
% convert x duration to num and plot transposed
im = imagesc(gca, datenum(timerange),temprange,FD.tempfrac',fracrange);
% plot a line with the time average value
plot(timerange,repmat(mean(FD.mean),1,2),'--b');
% make image transparant to show the datapoint from the first plot
im.AlphaData = .7;
% or change sort order from chlildren to depth (image depth = [-1 1])
ax = gca;
% ax.SortMethod= 'depth';
colormap(flipud(bone));
% set scales
% xlim(timerange);
xlim(duration({'9:37:00','9:38:00'}));
ylim([-20 0]);
% set labels
xlabel(['Time at ' datestr(FD.date)]);
ylabel('Temperature (°C)');
% set window and axes
fi.Position = [219 584 952 301];
ax.Position = [0.0683 0.1827 0.8897 0.7423];
end
2 Comments
Martin Ryba
on 7 Jul 2022
Note, to be pendantic, you'll need to adjust the time values to be from 0.5...N+0.5 times their timestep since the image data is nominally for the centers of the facets and imagesc fixes that for you. It's part of the reason people prefer imagesc over surf/mesh/pcolor.
Martin Ryba
on 7 Jul 2022
After experimenting, this seems to not work on R2021b; imagesc(gca,...) resets the axis range based on the datenums sent in which screws everything up.
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!