現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
App designer - deleting an unnamed plot
1 回表示 (過去 30 日間)
古いコメントを表示
Hi folks,
I have the following code for generating 1 or multiple plots on an image.
function ROI(app, index1, index2)
hold (app.Image, "on")
plot(app.Image, index1, index2, app.innerMarkerStyle, 'LineWidth', app.CrosshairThickness.Value, 'Color', app.crossHairColour, 'MarkerSize', app.CrosshairRadius.Value);
plot(app.Image, index1, index2, app.outerMarkerStyle, 'LineWidth', app.CrosshairThickness.Value, 'Color', app.crossHairColour, 'MarkerSize', app.CrosshairRadius.Value);
end
My question is, suppose there are 3 such plots. Is there a way to delete 1 and only 1 of them selectively?
Thanks
採用された回答
Cris LaPierre
2021 年 4 月 10 日
If you capture the chart line object for each plot, you could use that with the delete function to remove just that line from the plot.
btw, it's best practice to always pair hold on with a corresponding hold off.
Here's a simple example.
% Create a plot with 3 lines
a=plot(rand(1,5));
hold on
b=plot(rand(1,5));
c=plot(rand(1,5));
hold off
% Now delete one of the lines using the line object
delete(b)
16 件のコメント
Teshan Rezel
2021 年 4 月 11 日
thanks @Cris LaPierre, but I can't really name them since the position and number of plots is dependant on a user input. so to name each plot proceduraly is not somethig I'm keen to do as it may slow down the app considerably.
Cris LaPierre
2021 年 4 月 11 日
I don't think it will slow it down, but I can understand your concern.
Another way to approach this is to use findobj to collect all the line objects in a plot, and then using delete to remove a specific line object. It may be a little harder to ensure you are removing the intended line.
% Create a plot with 3 lines
plot(rand(1,5));
hold on
plot(rand(1,5));
plot(rand(1,5));
hold off
% Now delete one of the lines using the line object
h = findobj('Type','line')
h =
3×1 Line array:
Line
Line
Line
delete(h(2))
Teshan Rezel
2021 年 4 月 16 日
hi @Cris LaPierre, I've tried doing this on app designer but it isn't deleting the plot. Any ideas why it isn't working please?
function ButtonPushed(app, index)
app.Counts(end) = 0;
app.Percentages(end) = 0;
app.Counts(index) = app.Counts(index) + 1;
app.Counts(end) = sum(app.Counts, 1:7);
for i = 1 : 7
app.Percentages(i) = (app.Counts(i) / app.Counts(end)) * 100;
end
app.Percentages(end) = sum(app.Percentages, 1:7);
app.CokeTable.Data = [app.Counts, app.Percentages];
app.tallyOrder(end+1) = index;
app.numManualTally = app.numManualTally + 1;
if app.numManualTally >= app.numSamplesPerImage
app.imageNumber = app.imageNumber + 1;
app.numManualTally = 0;
DeleteCrosshairs(app);
end
end
function DeleteCrosshairs(app)
f = findobj(app.Image, 'Type', 'line');
delete(f(end));
delete(f(end-1));
end
Cris LaPierre
2021 年 4 月 16 日
編集済み: Cris LaPierre
2021 年 4 月 16 日
Is ButtonPushed supposed to have something to do with adding or removing a line plot from you image? It doesn't appear to be relevant.
I mocked up a simple example that plotted some lines on top of an image in app designer. The code in your DeleteCrosshairs succesfully removed 2 lines from the axes.
Teshan Rezel
2021 年 4 月 18 日
@Cris LaPierre apologies, I think I've not included the relevant functions! Here's the complete list!
methods (Access = private)
function ButtonPushed(app, index)
app.Counts(end) = 0;
app.Percentages(end) = 0;
app.Counts(index) = app.Counts(index) + 1;
app.Counts(end) = sum(app.Counts, 1:7);
for i = 1 : 7
app.Percentages(i) = (app.Counts(i) / app.Counts(end)) * 100;
end
app.Percentages(end) = sum(app.Percentages, 1:7);
app.CokeTable.Data = [app.Counts, app.Percentages];
app.tallyOrder(end+1) = index;
app.numManualTally = app.numManualTally + 1;
TallyCheck(app);
end
function ReverseButtonPushed(app, index)
app.Counts(end) = 0;
app.Percentages(end) = 0;
app.Counts(index) = app.Counts(index) - 1;
app.Counts(end) = sum(app.Counts, 1:7);
for i = 1 : 7
app.Percentages(i) = (app.Counts(i) / app.Counts(end)) * 100;
end
app.Percentages(end) = sum(app.Percentages, 1:7);
app.CokeTable.Data = [app.Counts, app.Percentages];
app.numManualTally = app.numManualTally - 1;
TallyCheck(app);
end
function ROI(app, index1, index2)
hold (app.Image, "on")
plot(app.Image, index1, index2, app.innerMarkerStyle, 'LineWidth', app.CrosshairThickness.Value, 'Color', app.crossHairColour, 'MarkerSize', app.CrosshairRadius.Value);
plot(app.Image, index1, index2, app.outerMarkerStyle, 'LineWidth', app.CrosshairThickness.Value, 'Color', app.crossHairColour, 'MarkerSize', app.CrosshairRadius.Value);
hold(app.Image, "off")
end
function DisplayCrosshairs(app)
I = imshow(app.img, "Parent", app.Image);
app.Image.XLim = [0 I.XData(2)];
app.Image.YLim = [0 I.YData(2)];
app.Width = app.Image.XLim;
app.Height = app.Image.YLim;
quarterHeight = range(app.Height)*0.125;
halfHeight = range(app.Height)*0.5;
threeQuarterHeight = range(app.Height)*0.875;
quarterWidth = range(app.Width)*0.125;
halfWidth = range(app.Width)*0.5;
threeQuarterWidth = range(app.Width)*0.875;
app.positionVector = {quarterWidth quarterHeight;halfWidth quarterHeight;threeQuarterWidth quarterHeight;quarterWidth halfHeight;halfWidth halfHeight;threeQuarterWidth halfHeight;quarterWidth threeQuarterHeight;halfWidth threeQuarterHeight;threeQuarterWidth threeQuarterHeight};
app.checkMatrix = [app.TopLeft.Value app.TopMiddle.Value app.TopRight.Value app.CentreLeft.Value app.CentreMiddle.Value app.CentreRight.Value app.BottomLeft.Value app.BottomMiddle.Value app.BottomRight.Value];
count = 0;
for i = 1 : 9
if app.checkMatrix(i) == 1
ROI(app, app.positionVector{i,1:2});
count = count + 1;
end
end
if count == 0
msgbox('Please select a quadrant for the crosshair to be displayed in');
end
end
function ResinThreshold(app)
imgGrey = rgb2gray(app.img);
[counts, ~] = imhist(imgGrey, 255);
T = otsuthresh(counts);
BW = imbinarize(imgGrey, T);
BW = bwareaopen(BW, app.AreaOpen.Value);
BW = imfill(BW, 'holes');
BW = bwperim(BW);
BW = imdilate(BW, ones(app.DilationMatrixDimensions.Value));
BW = imerode(BW, ones(app.ErosionMatrixDimensions.Value));
BW = imfill(BW, 'holes');
app.img = app.img.*repmat(uint8(BW),[1 1 3]);
end
function DisplayImage(app)
app.currentImage = fullfile(app.imageFolder(app.imageNumber).folder, app.imageFolder(app.imageNumber).name);
app.Image.Position = [0 0 app.UIFigure.Position(3:4)];
app.img = imread(app.currentImage);
if app.ThresholdResin.Value == 1
ResinThreshold(app);
end
DisplayCrosshairs(app);
app.ImageNumber.Value = app.imageNumber;
app.TotalNumber.Value = app.fileNumber;
app.numSamplesPerImage = sum(app.checkMatrix, 1:9);
end
function TallyCheck(app)
if app.numManualTally >= app.numSamplesPerImage
app.imageNumber = app.imageNumber + 1;
app.numManualTally = 0;
elseif app.numManualTally <= 0
app.imageNumber = app.imageNumber - 1;
app.numManualTally = app.numSamplesPerImage;
end
end
end
Cris LaPierre
2021 年 4 月 19 日
Still missing something. This code never even attempts to delete an object from your plot.
If you code is the combination of your two previous replies, then you you have two functions names ButtonPushed. They do different things, so perhaps you have a naming conflict?
Are you gettting any error messages? If so, share the entire message (all the red text).
Teshan Rezel
2021 年 4 月 19 日
Hey @Cris LaPierre, I think it's best if I attach the file as it saves some confusion...I don't think I'm explaining it well!
The way the app works is it will prompt you to select a folder with jpeg images on startup. Once selected, you can push each of the buttons on the left of the table to move to the next image. The number of times you need to click the buttons to move will depend on the number of crosshairs drawn, which can be varied by selecting the checkboxes in the "crosshair position" part of the "crosshair" tab.
Basically, I'm looking to delete a crosshair once a tally has been made. In other words, each time a button is pushed, a crosshair gets deleted.
Hope this is clear and I haven't missed anything out!
Cris LaPierre
2021 年 4 月 19 日
I've added the delete function you shared before to the app you shared previously. It is attached. I was able to confirm it deletes the crosshairs, but I'm definitely not comfortable navigating the app. Still, this should get your started.
Teshan Rezel
2021 年 4 月 19 日
hi @Cris LaPierre, below is an image of when the top left plot should have been removed, but isn't. I'm not seeing any error messages!
Cris LaPierre
2021 年 4 月 19 日
It removes the last crosshair added. However, pressing on a button also advances to the next image. If you had a way to go back to the previous image, you would see the crosshair removed.
Comment out the DisplayImage(app); in the corresponding callback function to prevent the images from advancing.
Teshan Rezel
2021 年 4 月 19 日
Hi @Cris LaPierre, thanks. This appear to work for only one crosshair. However, for more than one crosshair per image, the app will now not progress to the next image once the requisite number of tallies has been made...
Cris LaPierre
2021 年 4 月 19 日
You have the code, and I've shown you it works for a single crosshair. Now you can adapt that into your app to obtain the behavior you want.
You may need to think through your design and logic to accomplish that. Right now the confusion was because you are removing a crosshair from the visible image, but then the same code immediately advances to the next image, where all crosshairs are shown again, making it appear like the crosshair was not removed.
Teshan Rezel
2021 年 4 月 19 日
hi @Cris LaPierre, sorry about this...I was just being very stupid...well, more than usual! This has been a tremendous help, thank you!
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Line Plots についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
アジア太平洋地域
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)