imagesc or equivalent with datetime as x axis.

30 visualizaciones (últimos 30 días)
Chris Heintz
Chris Heintz el 24 de En. de 2022
Comentada: Benjamin Kraus el 21 de Sept. de 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 comentarios
Chris Heintz
Chris Heintz el 25 de En. de 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 el 29 de En. de 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.

Iniciar sesión para comentar.

Respuesta aceptada

Benjamin Kraus
Benjamin Kraus el 18 de En. de 2023
Editada: Benjamin Kraus el 20 de Sept. de 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 comentarios
Walter Roberson
Walter Roberson el 21 de Sept. de 2023
My memory is playing tricks on me; I thought that was new in R2023a.
Benjamin Kraus
Benjamin Kraus el 21 de Sept. de 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?

Iniciar sesión para comentar.

Más respuestas (3)

KSSV
KSSV el 25 de En. de 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 comentario
Chris Heintz
Chris Heintz el 28 de En. de 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.

Iniciar sesión para comentar.


Eric Delgado
Eric Delgado el 5 de Abr. de 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 comentario
Martin Ryba
Martin Ryba el 7 de Jul. de 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.

Iniciar sesión para comentar.


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

Categorías

Más información sobre Graphics Performance en Help Center y File Exchange.

Productos


Versión

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by