Issue with Plotting Data set based on Checkboxes in MATLAB App Designer

Hi,
I have an Excel file with data on a large number of devices. Each device has its own sheet within the Excel file.
I have a uitable with checkboxes setup in app designer so that when a check box is selected the data corresponding to that selection will be displayed on the plot. I need to be able to select more than one device at a time and all selected devices should appear on the plot.
When the user makes their selection by using the checkboxes in the uitable they then click a plot button, and their selected devices should be plotted. There is a clear button to clear the plot and the user should be able to repeat the process.
This is my code so far
%create the uitable, first column has the device names,
%second colunm has checkboxes
boxColumn = false(size(app.SheetName));
app.T = table(app.SheetName, boxColumn);
app.UITable.Data = app.T;
%callback to keep track of which checkboxes are selected
function UITableCellEdit(app, event)
indices = event.Indices;
newData = event.NewData;
if newData
app.SelectedDevices(end+1) = table2array(app.UITable.Data(indices(1),indices(2)-1));
else
app.SelectedDevices(ismember(app.SelectedDevices,app.UITable.Data(indices(1),indices(2)-1))) = [];
end
end
%selected devices plotted when button is pushed
function PlotButtonPushed(app, event)
probplot(app.UIAxes,app.Data(:,app.Data(app.SelectedDevices)));
legend(app.UIAxes,Sheetname,'-DynamicLegend','Location','best')
end
end
It is the last bit of code that I am having issues with. The error I'm getting is on the probplot line "Array indices must be positive integers or logical values."
I'd appreciate any help on this issue.
Andrew

3 Comments

It’s the imported sheet with the data of each device in it
This is the code
app.SheetName = sheetnames(app.filename1);
app.nSheets = length(app.SheetName);
%range of chosen data
range = 'D2:D501';
data = zeros(1,7);
for i = 1 : app.nSheets
Name = app.SheetName{i};
data = readtable(app.filename1,'Sheet',Name,'Range',range);
data1 = table2array(data);
app.Data(:,i) = data1;
end

Sign in to comment.

 Accepted Answer

I guess I would get the data to plot based on the selected checkboxes in app.UITable directly, without using app.SelectedDevices
probplot(app.UIAxes,app.Data(:,app.UITable.Data{:,2}));
and then, unless you need it for something else, you can do away with app.SelectedDevices (and therefore UITableCellEdit) entirely.

8 Comments

That worked perfectly. Removing the plot button is a much better solution too.
Thank you.
I am getting an error from the else part. I'm not sure why this is?
"Error using ismember. First argument must be text."
if newData
app.SelectedDevices(end+1) = table2array(app.UITable.Data(indices(1),indices(2)-1));
else
app.SelectedDevices(ismember(app.SelectedDevices,table2array(app.UITable.Data(indices(1),indices(2)-1)))) = [];
end
This is in UITableCellEdit still?
I'm not sure UITable still needs a CellEditCallback, but given that you want one, I would check the value and class of app.SelectedDevices. In particular, make sure it is initialized in the startupFcn to have an appropriate value (e.g., an empty cell array or empty String array if all devices are to be initially un-selected).
I ended up removing UITableCellEdit as you said. It works fine now.
The legend is proving to be very problematic for me.
I have tried
probplot(app.UIAxes,app.Data(:,app.UITable.Data{:,2}));
selectedDevices = app.UITable.Data{:,1};
legend(app.UIAxes,selectedDevices,'Location','best');
and
probplot(app.UIAxes,app.Data(:,app.UITable.Data{:,2}));
selectedDevices = app.Data(:,app.UITable.Data{:,1});
legend(app.UIAxes,selectedDevices,'Location','best');
Neither of these work as desired. The first one does actually display a legend, but it's not linked to the checkbox selection. It just displays the 1,2,3..... devices in the table depending on the number of checked checkboxes.
The second one doesn't work. I get an error: "Unable to use a value of type string as an index."
Do you know how I would fix this?
The legend working now however, it displays the dotted line symbol (for the line of best fit) and not the actual symbol that is used for plotting the data. I'm not sure if this is an issue with my code or if it's built into probplot().
This is the code. SheetName holds the names of each device
legendNames = app.SheetName(app.UITable.Data{:,2});
probplot(app.UIAxes,app.Data(:,app.UITable.Data{:,2}))
legend(app.UIAxes,legendNames,'Location','best');
Capture the output from probplot. That's an array of lines. The first half of the array is the data lines, so use those in the legend.
Here it is with random data:
ax = gca();
line_handles = probplot(ax,rand(10,3))
line_handles =
6×1 graphics array: Line (data) Line (data) Line (data) FunctionLine FunctionLine FunctionLine
legend(ax,line_handles(1:end/2),{'one','two','three'},'Location','Best')
In the context of your code, it would be:
line_handles = probplot(app.UIAxes,app.Data(:,app.UITable.Data{:,2}));
legend(app.UIAxes,line_handles(1:end/2),legendNames,'Location','Best');
This worked perfectly. Thank you!
I wouldn’t have thought to read the lines from the plot
Thank you for your help

Sign in to comment.

More Answers (0)

Categories

Find more on Develop Apps Using App Designer in Help Center and File Exchange

Products

Release

R2022a

Asked:

on 14 Jun 2022

Commented:

on 15 Jun 2022

Community Treasure Hunt

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

Start Hunting!