Azzera filtri
Azzera filtri

How do you make the x-axis in imagesc using datetime values?

63 visualizzazioni (ultimi 30 giorni)
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.
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');

Risposta accettata

Benjamin Kraus
Benjamin Kraus il 20 Set 2023
Modificato: Benjamin Kraus il 20 Set 2023
Starting in MATLAB R2023b, both the image and imagesc commands support datetime and duration data for the XData and YData properties.
x = [0 1];
t = datetime(2023,9,20)+hours([0 1]);
x = [0 1];
t = hours([1 23]);
If you are working with a release older than MATLAB R2023b you can use the workaround discussed in this answer.

Più risposte (4)

Walter Roberson
Walter Roberson il 27 Set 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.
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 Commenti
Damsel in Distress
Damsel in Distress il 30 Nov 2018
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?
Andrew McLean
Andrew McLean il 23 Mar 2020
I've tried with Matlab R2019a it doesn't work. Does it work with R2020a, documentation suggests not?

Accedi per commentare.

KSSV il 27 Set 2017
  1 Commento
Hannah il 27 Set 2017
I'm aware that you can manually change the tick marks on axis labels, but the benefit of the datetime function is that it changes as you zoom, hence my desire to use it. If I wasn't fussed about zooming, I'd use datetick

Accedi per commentare.

Erik il 25 Ott 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
% 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
%% 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
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
% 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';
% set scales
% xlim(timerange);
ylim([-20 0]);
% set labels
xlabel(['Time at ' datestr(]);
ylabel('Temperature (°C)');
% set window and axes
fi.Position = [219 584 952 301];
ax.Position = [0.0683 0.1827 0.8897 0.7423];
  2 Commenti
Martin Ryba
Martin Ryba il 7 Lug 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
Martin Ryba il 7 Lug 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.

Accedi per commentare.

Martin Ryba
Martin Ryba il 7 Lug 2022
See the wonderful dynamicDateTicks function. Just tried it and it is marvelous!


Community Treasure Hunt

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

Start Hunting!

Translated by