Is it possible to get minor grid lines to show when using datetime along x axis?

17 vues (au cours des 30 derniers jours)
Michael Speck
Michael Speck le 4 Nov 2021
Commenté : Dave B le 5 Nov 2021
Hi there,
I'm just starting out using datatime class types, but have found that when I plot with the datetime variable along the x-axis I can no longer get minor gridlines on the x-axis. This has the result of making plots harder to read/eye ball. Am I doing something wrong or is this just a feature of using datetime class type?
% Example of datetime not showing minor X axis grid.
% datetime vector
unixtime = [1.6e9:1:1.600001e9];
% Some y data
ydata = unixtime - 1.6e9;
%convert to datetime class
dTUnixtime = datetime(unixtime,'ConvertFrom','posixtime','TicksPerSecond',1e3,'Format','dd-MMM-yyyy HH:mm:ss.SSS');
% Make the plots
figure
tiledlayout(2,1)
nexttile
plot(dTUnixtime,ydata)
grid on
grid minor % Minor grid on! But does not show why?
title('X axis using class datetime')
nexttile
plot(unixtime,ydata)
grid on
grid minor % Minor grid on
title('X axis using class double')

Réponses (1)

Dave B
Dave B le 4 Nov 2021
You can absolutely have minor grid/ticks with a datetime x axis, but you'll need to pick your own minor tick values:
unixtime = [1.6e9:1:1.600001e9];
% Some y data
ydata = unixtime - 1.6e9;
%convert to datetime class
dTUnixtime = datetime(unixtime,'ConvertFrom','posixtime','TicksPerSecond',1e3,'Format','dd-MMM-yyyy HH:mm:ss.SSS');
plot(dTUnixtime,ydata)
grid on
grid minor
tickvals = xticks;
xax=get(gca,'XAxis');
xax.MinorTickValues = tickvals(1):diff(tickvals(1:2))/5:tickvals(end);
  2 commentaires
Michael Speck
Michael Speck le 5 Nov 2021
Thank you Dave, is there any way to automate this, so that the x minor grid auto adjusts as you zoom in and out, as the solution you proposed only works for a default zoom, see attach picture showing what happens once zoomed in. Cheers Michi
Dave B
Dave B le 5 Nov 2021
It's possible, but not altogether trivial:
  • You need a little alogrithm to pick minor ticks. The approach above is a little imperfect because it relies on the ticks being at the limits, which is maybe likely when not zoomed in but unlikely when zoomed in. It would look weird if your minor grid stopped at the limits, so you just need a bit of math to get your ticks to run all the way to the limits.
  • You need to be able to change when the zoom (really when the limits) change. That's actually not too terrible starting in 2021a, because there's a LimitsChangedFcn which you can use to set your minor ticks. Doing this in 2019b I think will require creating a listener which looks at the limits property (and you'd want to double check that they really changed in your callback). @Adam Danz points to a couple of posts that use a listener like this in his write-up of LimitsChangedFcn here: https://www.mathworks.com/matlabcentral/discussions/highlights/134586 (but if you're stuck on 19b and you want some help adding that listener I don't mind typing it up).
Here's an attempt at an implementation using LimitsChangedFcn, I think this is mostly correct but I just looked at it coarsely I might have missed something. This one does 5 minor ticks per major tick interval:
ax = gca();
grid(ax, 'minor')
ax.XAxis.LimitsChangedFcn = @setminorticks;
function setminorticks(ruler,event)
majortickdelta = diff(ruler.TickValues(1:2));
minortickdelta = majortickdelta / 5; % I just picked 5 arbitrarily
tickoffset = ruler.TickValues(1) - ruler.Limits(1);
firstminortick = ruler.TickValues(1) - floor(tickoffset/minortickdelta) * minortickdelta;
ruler.MinorTickValues = firstminortick:minortickdelta:ruler.Limits(2);
end

Connectez-vous pour commenter.

Produits


Version

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by