这是我的代码:
for p = 1:length(id_unique)
h=figure;
hold on
j = 1;
for i = 1:1:length(id)
if id_unique(p)==id(i)
h=plot([startdate(i),enddate(i)],[j,j],'ok-');
hold on
j = j + 1;
end
end
grid on
hold off
savefig([plotname,'.fig'])
print(plotname,'-djpeg','-r300')
close
end
% id: integer vector containing 50000 values
% id_unique: sorted unique values from vector 'id'
% startdate: datetime vector containing 50000 dates
% enddate: datetime vector containing 50000 dates
“ id ”向量中的每个元素/值都意味着一个事件,其中事件的startdate和enddate在“ startdate ”中的相应位置可用 enddate '向量。 因此,事件 id(1)的开始日期为 startdate(i),结束日期为enddate(i)。
程序从“ id_unique ”向量中获取值,对于在“ id ”中找到的每个匹配值,它会在图中绘制一条线,表示开头和结束时间。
例如,假设55是来自矢量' id_unique '的id值,我们在 id 中有1000次这个值。因此,对于55,创建的图表描绘了1000个单独的行,在事件开始时标记为“o”,在事件结束时标记为“o”,并且连接两个标记的行。
请查看从此代码块生成的附加图。如果 id_unique 有70个值,则会从此代码创建70个此类图表。在图像中,由于开始日期和结束日期之间的差异很小,许多线条太小,因此标记相互重叠,看起来像一个点。
现在问题出现在' id_unique '中的id值时,我们在' id '向量中有很多实例。当程序将各行绘制到100时,它的工作速度非常快,但在同一图中绘制300行后,程序变慢。当程序在同一图中绘制1000行时,每行大约需要5-7秒。因此,需要花费数小时才能生成包含多行的绘图。
有没有办法改进我的代码,使这些绘图生成更快。
答案 0 :(得分:4)
您不需要循环:
你可以使用类似的东西:
a = 1:0.1:4*pi;
b = sin(a); %vector that represent the start of each line
c = sin(a)+1; %vector that represent the end of each line
plot([b;c],[a;a],'-ko','markersize',2)
<强>结果:强>
函数plot
需要2个参数:x和y,但是,这就是世界美丽的原因,函数plot
可以管理多行。如果x和y是矩阵,matlab会将每列解释为新行。
答案 1 :(得分:1)
考虑到这一点后,我现在建议执行以下操作 - 而不是在绘图中创建多行,在后台生成大量对象,最好生成一个行每个情节,分为多个部分。如果startdate和enddate是1xlength(id)的向量,那么下面的代码会快得多,因为它将所有行连接在一起,其间有NaN值。这使得情节在该点断线。一切都非常快,不需要像我之前建议的那样与xlim和ylim混淆......
这是我的代码:
for p = 1:length(id_unique)
h=figure;
block=[startdate(id==id_unique(p));enddate(id==id_unique(p))];
x_vals=reshape([block;nan(1,size(block,2))],1,[]);
y_vals=reshape([(1:size(block,2));(1:size(block,2));nan(1,size(block,2))],1,[]);
plot(x_vals,y_vals,'ok-');
grid on
savefig([plotname,'.fig'])
print(plotname,'-djpeg','-r300')
close
end
我希望这对你有用。 (当然,如果你的startdate和enddate向量的长度(id)是1,那么你应该使用。&#39;在上面的第3行中转置它们。)
我不确定单独图的目的是什么,但如果有用的话,可以将它们全部绘制在同一图表上。那么代码就是:
h=figure;
hold on;
for p = 1:length(id_unique)
block=[startdate(id==id_unique(p));enddate(id==id_unique(p))];
x_vals=reshape([block;nan(1,size(block,2))],1,[]);
y_vals=reshape([(1:size(block,2));(1:size(block,2));nan(1,size(block,2))],1,[]);
plot(x_vals,y_vals,'Marker','o');
grid on
end
savefig([plotname,'.fig'])
print(plotname,'-djpeg','-r300')
close
这使Matlab可以使用其标准系列设置线型和颜色。它还允许您使用legend
功能添加标签。当然,如果id中的位置很重要,而不是使用y_vals的序列,则可以使用从find
获得的位置信息,将第4行和第6行更改为:
[~,index]=find(id==id_unique(p));
block=[startdate(index);enddate(index)];
y_vals=reshape(index;index;nan(1,size(block,2))],1,[]);
然后你会在一个图上看到所有id,其中id的不同值由颜色和线型区分。然后,您可以使用图例功能生成图例:
legend(num2str(id_unique.'));
(这假设id_unique是行向量。如果是列向量,则删除.'
)。
答案 2 :(得分:1)
以下是绘制2个不同标记的方法:
% some random data:
N = 50;
id = randi(5,N,1);
startdate = sort(randi(100,N,1));
enddate = startdate+randi(10,N,1);
% plotting:
ax = plot([startdate(:).'; enddate(:).'],[1:N; 1:N],'-k',...
startdate,1:N,'k<',enddate,1:N,'k>')
不需要向量之后的(:).'
,只是为了确保它们的方向正确plot
- 2行,startdate
高于enddate
}。
给出(随机):
如果要按id
将数据分组,并按照这种方式着色,则可以执行以下操作:
N = 30;
id = randi(5,N,1);
startdate = datetime(sort(736000+randi(100,N,1)),'ConvertFrom','datenum');
enddate = startdate+randi(20,N,1);
% plotting:
ax = plot([startdate(:).'; enddate(:).'],[1:N; 1:N],'-',...
startdate,1:N,'k<',enddate,1:N,'k>');
% coloring:
cmap = colormap('jet');
col = cmap(floor(linspace(1,64,numel(unique(id)))),:);
for k = 1:N
ax(k).Color = col(id(k),:);
ax(k).LineWidth = 2;
end
% set the legend:
c = 1;
leg_ent = zeros(numel(unique(id)),1);
for k = unique(id).'
leg_ent(c) = find(id==k,1,'first');
c = c+1;
end
legend(ax(leg_ent),num2str(unique(id)),'Location','SouthEast')
你会得到: