フィルターのクリア

Plot command inside a loop will not display all data unless drawnow is used

7 ビュー (過去 30 日間)
riverCN
riverCN 2020 年 11 月 27 日
コメント済み: riverCN 2020 年 12 月 1 日
I am working with 2017b.
I have a script that creates a single figure with 3x1 subplots, and it contains a for loop.
Withing the loop, I use errorbar to plot X, Y, Y_error data. Each loop iteration, I plot a single point at each subplot (always in the same axes with the 'hold' property set to 'on').
Sometimes (and it annoys me so much that it's not always), some data points are not displayed in the plots when the script finished running.
However, if I use the 'drawnow()' command after each time I call the errorbar, then all points are displayed.
Is this a known bug, or is it an somewhat expected behaviour?
% CODE MISSING - WHERE VARIABLES ARE DEFINED - BUT HOPEFULLY THIS IS GOOD ENOUGH FOR DEBUGGING
for idxSubject = 1 : numel(uniqueSubjects)
filter_subject = ismember(subjects, uniqueSubjects(idxSubject));
% Creates figures
figureName1 = sprintf('%s', uniqueSubjects{idxSubject});
hFigMeasurementPoints = figure('Position', [0 0 1 1], 'WindowStyle','docked', 'color', 'white', 'Name', figureName1, 'NumberTitle', 'off');
subplot(3,1,1);
for idxLocation = 1 : numel (uniqueLocations)
filter_locations = ismember(locations, uniqueLocations(idxLocation));
% computes the mean and SD of water and bg;
avgW = mean(W(filter_subject&filter_locations), 'omitnan');
avgSNR = mean(snr(filter_subject&filter_locations), 'omitnan');
avgSBR = mean(sbr(filter_subject&filter_locations), 'omitnan');
sdW = std(W(filter_subject&filter_locations), 'omitnan');
sdSNR = std(snr(filter_subject&filter_locations), 'omitnan');
sdSBR = std(sbr(filter_subject&filter_locations), 'omitnan');
set(0, 'CurrentFigure', hFigAveragedData);
subplot(3,1,1); hold on;
errorbar(idxSubject-0.2+0.4*idxLocation/numel(uniqueLocations), avgW, sdW, 's', 'MarkerSize', 10, 'LineWidth', 2, 'Color', myColors(idxLocation, :)); hold on;
title('W');
xlim([0.5, numel(uniqueSubjects)+0.5]);
ylim([65 85]);
xticks(1:numel(uniqueSubjects)); xticklabels(uniqueSubjects);
box on; grid on; grid minor;
legend(uniqueLocations);
subplot(3, 1,2); hold on;
errorbar(idxSubject-0.2+0.4*idxLocation/numel(uniqueLocations), avgSNR, sdSNR, 's', 'MarkerSize', 10, 'LineWidth', 2, 'Color', myColors(idxLocation, :)); hold on;
title('SNR');
xlim([0.5, numel(uniqueSubjects)+0.5]);
ylim([0 500]);
xticks(1:numel(uniqueSubjects)); xticklabels(uniqueSubjects);
box on; grid on; grid minor;
legend(uniqueLocations);
subplot(3, 1,3); hold on;
errorbar(idxSubject-0.2+0.4*idxLocation/numel(uniqueLocations), avgSBR, sdSBR, 's', 'MarkerSize', 10, 'LineWidth', 2, 'Color', myColors(idxLocation, :)); hold on;
title('SBR');
xlim([0.5, numel(uniqueSubjects)+0.5]);
ylim([0 0.12]);
xticks(1:numel(uniqueSubjects)); xticklabels(uniqueSubjects);
box on; grid on; grid minor;
legend(uniqueLocations);
% NOT ALL ITERATIONS WILL DISPLAY THE ERROR BAR POINT IN THE GRAPH IF I DON'T USE DRAWNOW HERE
drawnow();
end
end
  2 件のコメント
dpb
dpb 2020 年 11 月 27 日
Not a type of symptom have seen, no. Looking at the code might let somebody spot something peculiar in the way the code was written. Is it not possible to vectorize and call errorbar with all the data? That would be more efficient...
riverCN
riverCN 2020 年 12 月 1 日
Thank dpb. I've added the part of the code that takes care of the plotting. I omitted the part where I load data and define variables, but I don't think it's relevant for this question. I could indeed optimize the code by vectorizing this plotting process, but what for what I'm trying to do speed is not issue and clarity of the code is far more important, so that anyone picking on this easily understands what's happening.

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

採用された回答

Jan
Jan 2020 年 12 月 1 日
編集済み: Jan 2020 年 12 月 1 日
Missing plots can happen, if a timer or GUI callback changes the current figure. Instead of the instabkle method to set the current figure manually:
set(0, 'CurrentFigure', hFigAveragedData);
prefer to include the parents in the GUI commands explicitly:
% Omitted: set(0, 'CurrentFigure', hFigAveragedData);
hAxes = subplot(hFigAveragedData, 3,1,1); hold on;
errorbar(hAxes, idxSubject-0.2+0.4*idxLocation/numel(uniqueLocations), ...
Then users clicking in other open GUIs do not confuse the creation of diagrams.
If clarity of the code matters, avoid repeated code, e.g.:
match = (filter_subject & filter_locations);
avgW = mean(W(match), 'omitnan');
avgSNR = mean(snr(match), 'omitnan');
...
barProps = {'s', 'MarkerSize', 10, 'LineWidth', 2, 'Color', myColors(idxLocation, :)};
xData = (idxSubject - 0.2 + 0.4 * idxLocation / numel(uniqueLocations));
errorbar(xData, avgW, sdW, barProps{:});
hold on;
Is it really useful to set the ticks, labels and titles in each iteration? Better do this once only.
  1 件のコメント
riverCN
riverCN 2020 年 12 月 1 日
Great! Thanks for the suggestion on setting graphic properties. I had never tried it, but I thought it wouldn't work like that. Will use it from now on :)

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

その他の回答 (0 件)

カテゴリ

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

製品

Community Treasure Hunt

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

Start Hunting!

Translated by