You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
How to filter a signal(s) open in a UIAXES in matlab app designer?
1 view (last 30 days)
Show older comments
Hi All
I have a listbox from which I choose some signal names and plot them on my UIAXES. now wanted to make a filter button. how could I transfer those signals to the filtering button ?
maybe assuming I have 3 signals already plotted
2 Comments
farzad
on 6 Apr 2020
well, as you remember, I click on some filenames and I also have put a hold on button that I can hold the plots when being plotted on the UIAXES. once this is done and I have 3 plots present in the UIAXES, I want to press the filter button, with some defined variables let's say this one , get the plotted signals' variables : x-t and (then filter the x to y)
and plot the filtered signal over the same UIAXES
Accepted Answer
Ameer Hamza
on 7 Apr 2020
Please check the attached file. It gives a general idea of how to apply a filter on the current line plotted on a UIAxes. You can modify it according to your requirements.
37 Comments
farzad
on 7 Apr 2020
Edited: farzad
on 7 Apr 2020
Thank you very much ! this is great !!! only one thing, I wanted to keep the unfiltered together with the filtered values to compare and be able to save the filtered values to Excel later. How is that possible ? and also how do I grab the name of each unfiltered data I am filtering to add that to the filtered data plot in the legend ?
I did
fdata(i) = filter(b, a, app.UIAxes.Children(i).YData);
tem(i)= app.UIAxes.Children(i).XData;
plot(app.UIAxes,tem,fdata(i));
and I get an error : Subscripted assignment dimension mismatch.. and if I don't put an index, it gives the error index dimensions mismatch
Ameer Hamza
on 7 Apr 2020
Please check the updated app. I have shown how to use tag property to check which lines are needed to filter and which should be left unchanged.
farzad
on 7 Apr 2020
Thank you so much, what does
if strcmp(app.UIAxes.Children(i).Tag, 'f')
do ?
I mean why do we use tag ?
I needed to add another pushbutton to write the filtered Y (together with time columns) to excel files. but now I see that I can not just assign
app.fity= app.UIAXes.Children(i).DataY
or not ?
Ameer Hamza
on 7 Apr 2020
Edited: Ameer Hamza
on 7 Apr 2020
farzad, I gave the tag of 'f' and 'uf' to lines to identify whether to filter it or not. There are a total of 6 lines. Without tags, we cannot identify, which one of them needed to be filtered.
Similar to the plot, you can use the tag property to se which children are filtered and save their values.
farzad
on 8 Apr 2020
thank you very much. It just confused me a little bit. actually I had not noted the lines that define the tags in plotting.
but there is a question for me now. these lines are not under any for condition, and just repeat the same thing with the same name but different tag. so I don't understand how it plots both filtered and unfiltered over eachother.
Ameer Hamza
on 8 Apr 2020
If you see in the ListBoxValueChanged, it plots two lines with same x and y
p = plot(app.UIAxes, x, y);
p.Tag = 'uf'; % unfiltered
p = plot(app.UIAxes, x, y);
p.Tag = 'f'; % filtered
So these two lines overlap. When you click the filter button, one of these lines gets filtered, and the other remains the same. I found that this is the easiest way to draw both filtered and unfiltered lines.
farzad
on 8 Apr 2020
Thank you so much for your super amazing help !
ok now I wanted to remove the original plot after overlaying ( therefore I could have both of the method included in my code)
so I made another button to remove the original plot, but there is a logic failure from my side. since if I loop and inside the loop delete a UIAxes.children(I), I will have index exceeds matrix dimensions. any idea on how to resolve it ?
Ameer Hamza
on 8 Apr 2020
Edited: Ameer Hamza
on 8 Apr 2020
Start the loop in reverse order
for i=numel(app.UIAxes.children):-1:1
farzad
on 9 Apr 2020
dear Ameer! I did this , following your instructions, but I did the hold button a little bit differently. I have a problem : when I hold the plots and then delete the original plots, the last plot label dispears !
and when I uncheck hold plots, and then filter, it does not hold the original plot
then I wanted to save app.fity and app.fitt in savefiltered button function, but I am not sure if I can use them directly
function HoldPlotsCheckBoxValueChanged(app, event)
value = app.HoldPlotsCheckBox.Value;
% on pressing hold button, all previous lines will be deleted
delete(app.UIAxes.Children);
% if value==1
% hold(app.UIAxes);
% else
% hold(app.UIAxes, 'off');
% end
end
% Value changed function: FilesListBox
function FilesListBoxValueChanged(app, event)
switch app.HoldPlotsCheckBox.Value
case 0
cla(app.UIAxes)
drawnow;
% FocusUIFigure(app.UIFigure)
% app.UIFigure.Visible = 'off';
% app.UIFigure.Visible = 'on';
filename = app.FilesListBox.Value;
data = xlsread(filename);
p=plot(app.UIAxes, data(:,1), data(:,2));
p.Tag = 'uf'; % unfiltered
legend(app.UIAxes,filename);
p=plot(app.UIAxes, data(:,1), data(:,2));
p.Tag = 'f'; % filtered
legend(app.UIAxes,filename);
case 1
hold(app.UIAxes);
drawnow;
% FocusUIFigure(app.UIFigure)
% app.UIFigure.Visible = 'off';
% app.UIFigure.Visible = 'on';
filename = app.FilesListBox.Value;
app.names{end+1} = filename;
data = xlsread(filename);
p=plot(app.UIAxes, data(:,1), data(:,2));
p.Tag = 'uf'; % unfiltered
legend(app.UIAxes,app.names);
p=plot(app.UIAxes, data(:,1), data(:,2));
p.Tag = 'f'; % filtered
% plots(end+1)=pl;
legend(app.UIAxes,app.names);
hold(app.UIAxes);
end
end
% Button pushed function: UpdatefilesButton
function UpdatefilesButtonPushed(app, event)
files = dir('*.xlsx');
app.FilesListBox.Items = {files.name};
end
% Button pushed function: ClearPlotButton
function ClearPlotButtonPushed(app, event)
app.names={};
cla(app.UIAxes)
end
% Button pushed function: FilterButton
function FilterButtonPushed(app, event)
windowSize = app.window;
b = (1/windowSize)*ones(1,windowSize);
a = app.aval;
for i=1:numel(app.UIAxes.Children)
if strcmp(app.UIAxes.Children(i).Tag, 'f')
app.UIAxes.Children(i).YData = filter(b, a, app.UIAxes.Children(i).YData);
app.fitY= app.UIAxes.Children(i).YData;
app.fitt= app.UIAxes.Children(i).XData;
end
end
end
% Button pushed function: SaveFilteredButton
function SaveFilteredButtonPushed(app, event)
end
% Button pushed function: RemoveOriginalButton
function RemoveOriginalButtonPushed(app, event)
for i=numel(app.UIAxes.Children):-1:1
if strcmp(app.UIAxes.Children(i).Tag, 'uf')
delete(app.UIAxes.Children(i));
end
end
farzad
on 9 Apr 2020
Edited: farzad
on 9 Apr 2020
I also tried set(app.UIAxes.Children(i),'visible','off') , but then the legend colors lose their synchronization with the actual filtered plots
and also, it seems that plotting two plots, causes the legend color lose harmony with the visible ones. how could I resolve it ?
farzad
on 9 Apr 2020
dear Ameer, now the biggest problem is that if I have 6 plots in UIAxes, how to save them in the right order to one file ?
Ameer Hamza
on 9 Apr 2020
farzad, for the legend color issue, you will need to specify the colors in the plot statement explicitly. You can create a property named colors and assign it RGB values of several colors. You can also create a property named counter to keep track of how many colors are used. Something like this
p=plot(app.UIAxes, data(:,1), data(:,2), 'Color', obj.colors(obj.counter,:)); % define the color value
p.Tag = 'uf'; % unfiltered
legend(app.UIAxes,app.names);
p=plot(app.UIAxes, data(:,1), data(:,2), 'Color', obj.colors(obj.counter,:)); % define the color value
p.Tag = 'f'; % filtered
obj.counter = obj.counter + 1;
This will help in keeping track of colors.
For the order of UIAxes, you created them initially, so you know their handles and in which order they are placed. From that information, you should be able to know their order. Somehow, even if that information cannot be used, you can check the position property of uiaxes object to find out their order. Axes with lower x positions will be on the left as compared to any axis on the right.
farzad
on 9 Apr 2020
dear Ameer ! I was trying to write the data while pressing the button filter, but I was not successful, I do not get the variable fildat as a 2 column matrix to write it to excel but a 1D array. How to make it a 2 column matrix ?
function FilterButtonPushed(app, event)
windowSize = app.window;
b = (1/windowSize)*ones(1,windowSize);
a = app.aval;
for i=1:numel(app.UIAxes.Children)
if strcmp(app.UIAxes.Children(i).Tag, 'uf')
app.UIAxes.Children(i).YData = filtfilt(b, a, app.UIAxes.Children(i).YData);
app.fitY= app.UIAxes.Children(i).YData;
app.fitt= app.UIAxes.Children(i).XData;
name1=app.names{i};
[pathstr, name2, ext] = fileparts(name1)
name=strcat(name2,'filtered')
fildat=[app.fitt,app.fitY];
size(app.fitt)
size(fildat)
xlswrite(name,fildat,1);
end
end
Ameer Hamza
on 9 Apr 2020
Can you add a breakpoint at this line to see what is the dimensions of fildat? From the code it seems it should have two columns.
Ameer Hamza
on 9 Apr 2020
Ok, i get it. Those are row vectors. Use transpose
fildat=[app.fitt.',app.fitY.'];
farzad
on 9 Apr 2020
Excellent ! There is a new problem : I wanted to append each Children.Ydata to one row of app.fitY, but I can not subscribe it correctly and I get the error :
Subscripted assignment dimension mismatch.
if I swap to app.fitY(:,i) I get the error :
Assignment has more non-singleton rhs dimensions than non-singleton subscripts
function FilterButtonPushed(app, event)
windowSize = app.window;
b = (1/windowSize)*ones(1,windowSize);
a = app.aval;
for i=1:numel(app.UIAxes.Children)
if strcmp(app.UIAxes.Children(i).Tag, 'uf')
app.UIAxes.Children(i).YData = filtfilt(b, a, app.UIAxes.Children(i).YData);
app.fitY(i,:)= app.UIAxes.Children(i).YData;
app.fitt(i,:)= app.UIAxes.Children(i).XData;
end
end
Ameer Hamza
on 9 Apr 2020
Use something like this
windowSize = app.window;
b = (1/windowSize)*ones(1,windowSize);
a = app.aval;
app.fitY = [];
app.fitt = [];
for i=1:numel(app.UIAxes.Children)
if strcmp(app.UIAxes.Children(i).Tag, 'uf')
app.UIAxes.Children(i).YData = filtfilt(b, a, app.UIAxes.Children(i).YData);
app.fitY = [app.fitY app.UIAxes.Children(i).YData];
app.fitt = [app.fitt app.UIAxes.Children(i).XData];
end
end
farzad
on 9 Apr 2020
no if I have more than one plot, this will save only the last filtered plot info to the 2 variables fitY and fitt. They should take each array , relating to each plot in each of their rows, something I did not succeed to do
Ameer Hamza
on 9 Apr 2020
This will not just save last plot, it will save all the plots inside the for loop. It append them as a single row. If you want to save each plot in a seperate row then change it to
app.fitY = [app.fitY; app.UIAxes.Children(i).YData];
app.fitt = [app.fitt; app.UIAxes.Children(i).XData];
But this require that all plots have same number of points.
farzad
on 10 Apr 2020
a problem :
I always have difficulty in getting the parameter from another Editfield or button and use it in another in app designer, it sometimes works sometimes not.
For example , I wanted to plot from a file that contains more columns , so plot all other columns vs the first column that is supposed to be the horizontal axis. in this case, I should name each plot and I should take this names from the user plus the filename I hit on the listbox. so I created Editfield and wrote a default value X in it.
then I created a public property xedit=' ' , and then under editfield function :
% Value changed function: EditField
function EditFieldValueChanged(app, event)
app.xedit = app.EditField.Value;
app.yedit = app.EditField.Value;
app.zedit = app.EditField.Value;
end
but this did not work, I mean did I wrongly use Value changed function and I had to use value changing function ? or what would be the error ? app.xedit =' ' always in the code
Ameer Hamza
on 10 Apr 2020
What do you mean by did not work. Did the value does not get assigned to varaibles. Add a breakpoint at this line to check what is teh value of app.EditField.Value.
farzad
on 10 Apr 2020
I mean that the code does not get the default value 'X' from the edit field to strcat it with the filename.
there was Editfieldvaluechanged and I used that not the value changing one.
farzad
on 10 Apr 2020
I also have a numeric edit field and the code gets that value without problem, but with the same method, the text input for these edit field does not work and they remain empty char
Ameer Hamza
on 10 Apr 2020
I am not sure. app.EditField.Value should return the text inside the edit field as a char array. Make sure that the callback function is assigned to the correct edit field.
farzad
on 10 Apr 2020
It resolved by opening and closing matlab, sometimes adding new variables are not uploaded to matlab base.
by the way , one doubt : If I have to choose a file in the listbox, I should have more than 1 file, at least two, to be able to hover from one over the other. what if I have only one file in the folder ?
Ameer Hamza
on 10 Apr 2020
Can you show the picture of the listbox and what is the issue with single file?
farzad
on 11 Apr 2020
Sure , here is the listbox. If I have only one single file, I can not hover with mouse over it and click it, despite it is even highlighted , nothing can be plotted
Ameer Hamza
on 11 Apr 2020
Yes, that seems to be an issue. MATLAB only generates a callback when the value is changed. What about adding a dummy field which user can click when when no file is selected.
Ameer Hamza
on 11 Apr 2020
By dummy field, I mean, just add an additional item in the list, for example "none", after all the file names. This will allow user to select "none" and then reselect the filename.
farzad
on 11 Apr 2020
Another problem : new : Using the plot children, I tried to plot the acceleration, but this plots nothing , why ?
app.Yd = [];
app.Xt = [];
for i=1:numel(app.UIAxes.Children)
% if strcmp(app.UIAxes.Children(i).Tag, 'uf1')
i;
app.Yd = [app.Yd; app.UIAxes.Children(i).YData];
app.Xt = [app.Xt; app.UIAxes.Children(i).XData];
% end
end
tf= app.Xt.'; %satri be sotuni
yf=app.Yd.';
dyf=gradient(yf)./gradient(tf);
ddyf=gradient(dyf)./gradient(tf);
cla(app.UIAxes)
drawnow;
pa1=plot(app.UIAxes, tf(:,1), ddyf(:,1))
pa1.Tag = 'acc1'; % unfiltered
hold(app.UIAxes,'on');
farzad
on 11 Apr 2020
pa1has data but nothing is drawn
pa1 =
Line with properties:
Color: [0 0.4470 0.7410]
LineStyle: '-'
LineWidth: 0.5000
Marker: 'none'
MarkerSize: 6
MarkerFaceColor: 'none'
XData: [1×15360 double]
YData: [1×15360 double]
ZData: [1×0 double]
More Answers (0)
See Also
Categories
Find more on Startup and Shutdown in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- 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)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)