imagesc or equivalent with datetime as x axis.
24 次查看(过去 30 天)
显示 更早的评论
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);
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 个评论
Walter Roberson
2022-1-29
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.
采纳的回答
Benjamin Kraus
2023-1-18
编辑:Benjamin Kraus
2023-9-20
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 个评论
Benjamin Kraus
2023-9-21
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?
更多回答(3 个)
KSSV
2022-1-25
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)
Eric Delgado
2022-4-5
@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 个评论
Martin Ryba
2022-7-7
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.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Graphics Performance 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!