+60k Lines on one plot - Too slow

17 ビュー (過去 30 日間)
Ömer Yaman
Ömer Yaman 2022 年 6 月 25 日
コメント済み: Ömer Yaman 2022 年 6 月 27 日
Dear all,
I need to plot more than 60k lines. I'm doing it in a for loop. It takes too much time, about 170 seconds with the rest of the code. Is there any quicker way?
And also saveas(fig ... command takes too much time as well. About 60 seconds. I would like to save my plot as a png. file.
What are your suggestions to reduce time cost.
Best Regards,
  4 件のコメント
Adam Danz
Adam Danz 2022 年 6 月 25 日
I agree with @Jonas that it would be helpful to see your plot (ie, screenshot).
It's hard to imagine how 60k lines would be useful in a visualization and we may be able to suggest alternative approaches, or, perhaps, it will make instance sense to us why 60k lines is useful.
If your plotting inputs are vectors, it looks like you could compute all of the y values (slopes+energy+slopes) and store the results in a matrix and the plot it all at once using the template line below. However, that will still produce 60k line objects while will be painfully slow.
h = plot(1:5, rand(10,5))
h =
10×1 Line array: Line Line Line Line Line Line Line Line Line Line
Ömer Yaman
Ömer Yaman 2022 年 6 月 25 日
At that moment, I have my code on the computer that I have in my university. I'will share the plot asap from here.
Task is given to me is like that, I have about 60500 different points which has 6 different value for different time domain. I am supposed to visualize that the generated lines (for each point for 6 different increasing values, basicaly y=mx+n) has slopes that it should not be higher than a certain amount of mean slope value among all slopes and should not be lower too.
Calculations are correct but the time cost is too much. I'm seeking more optimized coding to save time.

サインインしてコメントする。

採用された回答

Adam Danz
Adam Danz 2022 年 6 月 25 日
編集済み: Adam Danz 2022 年 6 月 25 日
Another idea is to plot your 60k lines as a 2D density plot (initially suggested in this thread).
Pros:
  • 1 graphics object, light weight plot
  • simple to compute & simple to plot
  • you can see the density patterns created by overlapping lines etc.
  • If there is a strong median curve, you'll see it in the plot
Cons:
  • Single curves won't appear in the plot (but you wouldn't see many single curves anyway with 60k lines)
  • Outliers may become difficult or impossible to see
Example
Create 10k line series that follow a general pattern with varying amounts of noise. I'll use the same x-coordinates but this works just as well if the x-values vary too.
gaus = @(x,mu,sig,amp,vo)amp*exp(-(((x-mu).^2)/(2*sig.^2)))+vo;
x = 0:850;
n = 1e4;
y = zeros(n,numel(x));
rng('default') % to reproduce these results
for i = 1:n
mu = rand(1)*175+300;
sig = rand(1)*100+150;
amp = randn(1)*20+30;
vo = rand(1)*10;
y(i,:) = gaus(x,mu,sig,amp,vo);
end
Now, let's plot 50 random lines to see what they look like. Use randperm to do the random selection.
figure
m = 50;
selection = randperm(n,m);
plot(x, y(selection,:))
title(sprintf('%d random curves from %d',m,n))
axis tight
Plot the 2D density using histogram2()
% Replicate the X-vector (skip this if your x values vary for each curve)
xRep = repmat(x, n, 1);
% plot the bivariate historgram
figure
h = histogram2(xRep(:),y(:),'DisplayStyle','tile','ShowEmptyBins','on');
title('Bivariate density of curves')
cb = colorbar();
ylabel(cb,'Number of curves')
Alternatively, you could turn off the empty bins to see the shape of the entire dataset
figure
h = histogram2(xRep(:),y(:),'DisplayStyle','tile');
title('...ignoring empty bins')
cb = colorbar();
ylabel(cb,'Number of curves')
  2 件のコメント
dpb
dpb 2022 年 6 月 26 日
@Adam Danz, that's a very good idea for such large datasets, indeed. I've used such in the past as well but didn't think to suggest it here...
Ömer Yaman
Ömer Yaman 2022 年 6 月 27 日
Thank you, I will go with this solution.

サインインしてコメントする。

その他の回答 (2 件)

dpb
dpb 2022 年 6 月 25 日
編集済み: dpb 2022 年 6 月 25 日
This is way too much data to plot on single figure realistically, of course it's going to take time.
But, the use of a loop and plot is the slowest way possible -- you're computing/drawing every single line individually instead of using the power of MATLAB in being vectorized...
y=[slopes(:,1)*energy+slopes(i,2)].'; % generate y(i,j) by column
hL=plot(energy,y); % plot the result
Here on a not terribly upscale system,
>> tic,y=m*e;toc
Elapsed time is 0.001305 seconds.
>> tic,hL=plot(e,y);toc
Elapsed time is 15.350194 seconds.
>> delete(hL)
>> close
although it took the renderer quite some additional time to actually draw and display the figure -- and at least as long to delete 60K graphics handles.
Since there are only some 1-2K pixels on a monitor anyway, 60K points is some 60X the possible density to be able to display; I would strongly suggest decimating the y array by at least a factor of 10 and likely you'll be unable to see any difference in the result at factors approaching 100X.
  1 件のコメント
Ömer Yaman
Ömer Yaman 2022 年 6 月 25 日
Thank you for your help, I'll try your suggestion asap.

サインインしてコメントする。


Image Analyst
Image Analyst 2022 年 6 月 25 日
Plot just a subsample of the curves. You'll never be able to see all 60k lines anyway, so just pick, say 1000 of them at random and plot those. You'll probably still get the general idea of what all the data would look like if you could have plotted them.
  1 件のコメント
Ömer Yaman
Ömer Yaman 2022 年 6 月 27 日
Thank you for your help, I will keep the math but reduce the number of lines which is plotted.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLine Plots についてさらに検索

製品


リリース

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by