用 disconnected/discrete 行创建图
Creating plots with disconnected/discrete lines
这是我的代码:
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'向量中的每个elements/values表示一个事件,其中事件的开始日期和结束日期在'[=29=中的相应位置可用]startdate' 和 'enddate' 向量。
因此,事件 id(1) 的开始日期为 startdate(i),结束日期为 enddate(i).
程序从“id_unique”向量中获取一个值,并针对在“id”中找到的每个匹配值, 它在图中画一条线,表示事件的开始和结束时间。
例如,假设 55 是来自向量 'id_unique' 的一个 id 值,并且我们在 id[= 中有这个值 1000 次41=]。因此,对于 55,创建了一个图,描绘了 1000 条单独的线,在事件开始时有一个标记 'o',在事件结束时有一个标记 'o',并且有一条线连接两个标记。
请查看从该代码块生成的附件图。如果 id_unique 有 70 个值,则将从该代码创建 70 个这样的图。图像中,由于开始日期和结束日期之间的差异很小,因此许多线太小,因此标记相互重叠,看起来像一个点。
现在问题来了,对于“id_unique”中的一个 id-value,我们在“”中有很多它的实例id' 向量。当程序将单条线绘制到 100 条时,它运行得非常快,但在同一图中绘制 300 条线后,程序变慢了。当程序在同一张图中绘制 1000 条线时,每条线大约需要 5-7 秒。所以生成一个多行的图需要很多小时。
有没有办法改进我的代码,使这些绘图生成更快。
考虑更多之后,我现在建议执行以下操作 - 与其在绘图中创建多条线,这会在背景中生成大量对象,不如生成 一个 每个图的行,被分成多个部分。如果 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
我希望这对你更好。 (当然,如果您的开始日期和结束日期向量的长度(id)乘以 1,那么您应该在上面的第 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函数生成图例了:
legend(num2str(id_unique.'));
(假设id_unique是行向量,如果是列向量,去掉.'
)。
你不需要循环:
你可以使用类似的东西:
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 将每列解释为一个新行。
这里是绘制 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')
你将得到:
这是我的代码:
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'向量中的每个elements/values表示一个事件,其中事件的开始日期和结束日期在'[=29=中的相应位置可用]startdate' 和 'enddate' 向量。 因此,事件 id(1) 的开始日期为 startdate(i),结束日期为 enddate(i).
程序从“id_unique”向量中获取一个值,并针对在“id”中找到的每个匹配值, 它在图中画一条线,表示事件的开始和结束时间。
例如,假设 55 是来自向量 'id_unique' 的一个 id 值,并且我们在 id[= 中有这个值 1000 次41=]。因此,对于 55,创建了一个图,描绘了 1000 条单独的线,在事件开始时有一个标记 'o',在事件结束时有一个标记 'o',并且有一条线连接两个标记。
请查看从该代码块生成的附件图。如果 id_unique 有 70 个值,则将从该代码创建 70 个这样的图。图像中,由于开始日期和结束日期之间的差异很小,因此许多线太小,因此标记相互重叠,看起来像一个点。
现在问题来了,对于“id_unique”中的一个 id-value,我们在“”中有很多它的实例id' 向量。当程序将单条线绘制到 100 条时,它运行得非常快,但在同一图中绘制 300 条线后,程序变慢了。当程序在同一张图中绘制 1000 条线时,每条线大约需要 5-7 秒。所以生成一个多行的图需要很多小时。
有没有办法改进我的代码,使这些绘图生成更快。
考虑更多之后,我现在建议执行以下操作 - 与其在绘图中创建多条线,这会在背景中生成大量对象,不如生成 一个 每个图的行,被分成多个部分。如果 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
我希望这对你更好。 (当然,如果您的开始日期和结束日期向量的长度(id)乘以 1,那么您应该在上面的第 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函数生成图例了:
legend(num2str(id_unique.'));
(假设id_unique是行向量,如果是列向量,去掉.'
)。
你不需要循环:
你可以使用类似的东西:
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 将每列解释为一个新行。
这里是绘制 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')
你将得到: