이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
App designer - deleting an unnamed plot
조회 수: 2 (최근 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!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 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 (한국어)