Filter löschen
Filter löschen

imagesc or equivalent with datetime as x axis.

49 Ansichten (letzte 30 Tage)
Chris Heintz
Chris Heintz am 24 Jan. 2022
Kommentiert: Benjamin Kraus am 21 Sep. 2023
I'd like to use imagesc (or some other function that produces similar output) to plot some data with a numerical y axis and datetime x axis. I'd strontly prefer not to use datenums for the x axis, because the axis doesn't update when zoomed, the datatips aren't fomatted nicely (like they are for plots with datetime as the x axis), and subsequent plots don't work with datetime as the x axis.
Example:
clear; close all;
times = datetime('now') + hours(0:1:50);
yvals = 0:5:100;
colors=randn(size(yvals,2),size(times,2)) + yvals';
im=imagesc(times,yvals,colors);
Error using image
Image XData and YData must be vectors.

Error in imagesc (line 52)
hh = image(varargin{:}, 'CDataMapping', 'scaled');
set(gca,'YDir','normal');
pcolor seems to work, but the offsetting is undesirable (my data is "face centered", not "vertex centered"), as are the gridlines.
I've tried various things like setting the x axis to a DatetimeRuler and this method using duration with no success.
Thanks!
  3 Kommentare
Chris Heintz
Chris Heintz am 25 Jan. 2022
That's unfortounate. Can you think of any possible workarounds? Is there a way to have an extra set of axes that would be numeric and align them with the datetime axis?
Walter Roberson
Walter Roberson am 29 Jan. 2022
I do not think you would be able to do it with linkaxes(), but you might be able to use a listener to listen for a resize or pan event.
I seem to recall that there is a way to coerce an axes to be a particular type, but I have forgotten all of the details.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Benjamin Kraus
Benjamin Kraus am 18 Jan. 2023
Bearbeitet: Benjamin Kraus am 20 Sep. 2023
If you are using MATLAB R2023b or newer:
Starting in MATLAB R2023b, you can now work with images on datetime rulers natively.
times = datetime('now') + hours(0:1:50);
yvals = 0:5:100;
colors=randn(size(yvals,2),size(times,2)) + yvals';
im=imagesc(times,yvals,colors);
set(gca,'YDir','normal');
If you are using MATLAB older than R2023b, continue reading for the old solution:
It is a bit of a hack, but another option (if you want to continue using imagesc) is to "preconfigure" the axes for datetime using a command (such as plot) that does support datetime, then leverage ruler2num to convert your data into double for passing to imagesc.
One reason for ruler2num is to allow you to add objects that don't (yet) support datetime natively to be added to an axes that has existing datetime data. This is just leveraging that approach, but then deleting the "other data".
Note that in order to use this approach:
  • You have to "preconfigure" the axes before any other objects are added to the axes. In other words: The first object added to the axes is used to set-up the axes to support datetime data. If there are existing objects and the axes is not already configure for datetime data, adding datetime data will throw an error.
  • You need to use hold on because otherwise the first thing the imagesc command will do is reset the axes configuration back to the default (numeric) configuration. This means that you need to manually set any axes properties that are normally set by the imagesc command.
For example:
figure
times = datetime('now') + hours(0:1:50);
yvals = 0:5:100;
colors=randn(size(yvals,2),size(times,2)) + yvals';
% This command will configure the axes for use with datetime
% Then delete the line created by the plot command.
delete(plot(times(1), yvals(1)));
% Now hold is required, because otherwise the axes will be reset by the
% image command.
hold on
% Now you can convert from datetime to numerics using ruler2num
x = ruler2num(times, gca().XAxis);
% Now pass the double data to imagesc.
im=imagesc(x,yvals,colors);
% Finally, because hold was on, you need to manually set the limits (which
% is normally done for you by imagesc) and turn on the box. I ommited
% flipping the YDir becuse you seem to want that set to 'normal' anyway.
axis tight
box on
hold off
I'm aware this workaround isn't ideal, and I'm working on native support for datetime data in the imagesc command, so this workaround should not be necessary.
  3 Kommentare
Walter Roberson
Walter Roberson am 21 Sep. 2023
My memory is playing tricks on me; I thought that was new in R2023a.
Benjamin Kraus
Benjamin Kraus am 21 Sep. 2023
It is hard for me to keep track (given that we were almost done with R2023b when R2023a shipped for customers), but I did just confirm that this feature was implemented for R2023b. Maybe you are thinking of the prerelease?

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (3)

KSSV
KSSV am 25 Jan. 2022
times = datetime('now') + hours(0:1:50);
yvals = 0:5:100;
colors=randn(size(yvals,2),size(times,2)) + yvals';
im=imagesc(colors);
set(gca,'YDir','normal');
xticks = 1:5:50; %adjust as appropriate, positive integers only
xlabels = cellstr(times(xticks) ); %time labels
% xlabels = num2str( ( T(xticks)) ); % you don't need this
set(gca, 'XTick',xticks, 'XTickLabel', xlabels);
xtickangle(45)
  1 Kommentar
Chris Heintz
Chris Heintz am 28 Jan. 2022
Thank you for your effort. However this has the same issues as using datenums, and additionally imposes the additional restriction that the x axis for the entire plot be positive integers.

Melden Sie sich an, um zu kommentieren.


Eric Delgado
Eric Delgado am 5 Apr. 2022
@Chris Heintz, "mesh function" is the answer that you are looking for.
times = datetime('now') + hours(0:1:50);
yvals = 0:5:100;
colors = randn(size(yvals,2),size(times,2)) + yvals';
fig = figure;
ax = axes(fig);
[X, Y] = meshgrid(times, yvals);
mesh(ax, X, Y, colors, 'FaceColor', 'interp')
view(ax, 0,90);
set(ax, 'XLim', [times(1), times(end)], 'YLim' , [yvals(1), yvals(end)])
  1 Kommentar
Martin Ryba
Martin Ryba am 7 Jul. 2022
imagesc interprets the values of the pixels to be at the centers of each coordinate, whereas surf/mesh/pcolor/etc. interpret them to be at the edges of the coordinates and truncate bits appropriately. It's not what most of us want.

Melden Sie sich an, um zu kommentieren.


Martin Ryba
Martin Ryba am 7 Jul. 2022
See the wonderful dynamicDateTicks function. I just tried it and it's marvelous!

Kategorien

Mehr zu Axes Appearance finden Sie in Help Center und File Exchange

Produkte


Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by