0

我正在尝试绘制 63 年的月度数据,并且一些标签正在重复(用箭头表示),如下图所示:

为了处理 x-labels,我使用了以下代码:

xdate = datenum (datestring2, 'yyyy/mm');
plot (xdate,data1.data(:,4), 'b', xdate,data1.data(:,6),'r', ...
xdate,data1.data(:,8),'k', xdate,data1.data(:,10),'g');
xtic=xdate(1):12:xdate(end); 
set(gca,'XTick',xtic);
datetick('x', 'mm/yyyy', 'keepticks');

我该如何解决这个问题?

4

2 回答 2

3

您可以利用以下的结转功能datenum()

out = datenum(2000,1:14,1);

让我们验证一下:

datestr(out)
ans =
01-Jan-2000
01-Feb-2000
01-Mar-2000
01-Apr-2000
01-May-2000
01-Jun-2000
01-Jul-2000
01-Aug-2000
01-Sep-2000
01-Oct-2000
01-Nov-2000
01-Dec-2000
01-Jan-2001
01-Feb-2001

现在将它们设置为Xtick

set(gca,'Xtick',out)

编辑:使用开始结束日期

% Provide example initial and final date
in = '20100324';
fi = '20130215';

% Decompose with datevec, count number of months, and skip one month if day > 1
infi    = datevec({in,fi},'yyyymmdd');
nmonths = diff(infi(:,1:2))*[12 1]' + infi(1,2);
skipone = infi(1,3) ~= 1;

% Calculate dates 
out = datenum(infi(1), (infi(1,2) + skipone):nmonths, 1);
于 2013-04-13T18:50:09.120 回答
2

你的表情xtic=xdata(1):12:xdate(end)说你想要每 12 天打一次勾;通常这意味着您将获得两个(甚至三个)重复的月份。一个快速而肮脏的解决方案是

xtic = xdata(1):30:xdate(end);

但在某些情况下,这可能会跳过二月,并且当您运行大量月份时将是错误的。

为了正确解决这个问题,您需要在每个月的第一天放置刻度。一种可能的方法是:

xdate = datenum(datestring2, 'yyyy/mm');
d1 = datevec(xdate(1)); % [year, month, date, hour, min, sec]
d2 = datevec(xdate(end)+30); % one month past the last data point
nm = ceil((xdate(end) - xdate(1))*12/365); % whole number of months
mv = mod((1:nm) + d1(2) - 2, 12) + 1;  % months
yv = d1(1) + floor(((1:nm) + d1(2) - 1)/12); % years
ymdv = [yv' mv' ones(nm,1)];  % year, month, day for each tic
xtic = datenum(ymdv); % will turn this into "the first of every month"

编辑Oleg Komarov 的回答指出了一种在每个月的第一天生成抽动的更清洁的方法 - 这是使用datenum可以处理大于 12 个月的事实。您可能可以通过使用使上述代码更紧凑和更清洁方法(例如,您可以省略 的mod操作mv,而只使用 d1(1) 作为年份)。但有时明确说明你在做什么并不是一件坏事。

于 2013-04-12T19:44:38.827 回答