How can I use sliders to do interactive plots from a structure array?

I have a structure array containing a B number of matrixes of [MxN] data, where M is different for every set and N is the same for every set of data.
I would like to have only one plot, where using two sliders I can choose between the B sets of data and N columns. I have only found examples of how to use a slider to update a plot changing a parameter (like the damping factor of a sinusoid), but nothing useful for my case.

4 件のコメント

Stijn Haenen
Stijn Haenen 2020 年 8 月 4 日
Something like this:
close all
clear
b=struct;
for i=1:10
b(i).data=ones(10)*i.*(i:i:i*10); %creating struc with data
end
fig = figure;
s1 = uicontrol('Parent',fig,'Style','slider','Position',[81,1,419,23],...
'value',0.1, 'min',0.1, 'max',10);
s2 = uicontrol('Parent',fig,'Style','slider','Position',[81,24,419,23],...
'value',0.1, 'min',0.1, 'max',10); %creating sliders
hold on
while 1>0
plot(b(ceil(s1.Value)).data(:,ceil(s2.Value)),'b') %plot data
pause(0.1)
delete(fig.CurrentAxes.Children)
end
Seth Meiselman
Seth Meiselman 2020 年 9 月 17 日
Could you give an example of this structure array- how you've composed it in code? I think the solution above seems reasonable unless there is something specific about how you've constructed this data set. Are the matrices enumerated or labeled in the structure?
Alessandro Giacetti
Alessandro Giacetti 2020 年 9 月 17 日
A =
1×95 struct array with fields:
Batch
You can access the matrixes typing A(i).Batch with i = 1:95. The solution above works but it is a bit rough because it creates that infinite loop. I would like to use the callback instead.
Rik
Rik 2020 年 9 月 17 日
If you write code using that callback (and I encourage you to try something yourself), make sure to round the value, as you're not guaranteed an integer.

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

 採用された回答

Seth Meiselman
Seth Meiselman 2020 年 9 月 18 日
編集済み: Seth Meiselman 2020 年 9 月 18 日

2 投票

There's probably a better, cleaner way, but it should work.
clear all;
close all;
% Some junk data sets in a structure defined as A(b).data(m,n)
imax = 10;
jmax = 10;
datax = 0:pi/12:(23*pi);
for i=1:imax
for j=1:jmax+i
% Creating data struc A(b).data(m,n)
% y = y0 + sin(w*x)
blx(i).data(j,:)= i+sin((j/5)*datax);
end
sizej(i) = size(blx(i).data(:,:),1);
end
% Plot different data sets according to slider location.
slider_plot(blx, datax, imax, jmax, sizej);
function [] = slider_plot(blx, datax, imax, jmax, sizej)
% Define figure window, normalized to fit arb. screen
S.fh = figure('units','normalized','name','slider_plot',...%%%%
'Position', [0.515 0.025 0.415 0.87] );
% Define axes so that room is available in figure window for sliders
S.ax = axes('unit','normalized','position',[0.1 0.5 0.8 0.45]);
% There might be a better way to substitute data sets, but this works.
S.y = @(par) blx(par(1)).data(par(2),:);
% Define inital parameter values for input
S.a = 1;
S.b = 1;
% Plot 'junk data' as reference
S.p1 = scatter(datax,S.y([S.a,S.b]),'k');
hold on;
% Plot new data set on top of 'junk data' for visual comparison
S.p2 = plot(datax,S.y([S.a,S.b]));
hold off;
update(S);
% Slider for slope parameter:
S.aSlider = uicontrol('style','slider','unit','normalized',...
'position',[0.2 0.1 0.7 0.01],...
'Min',1,'Max',imax,'Value', 1,...
'sliderstep',[0.1 0.1],'callback', {@SliderCB, 'a',sizej});
% Add a text uicontrol to label the slider.
txta = uicontrol('Style','text','unit','normalized',...
'position',[0.2 0.11 0.7 0.02],...
'String','Data set "blx(i)"');
% 2nd Slider:
S.bSlider = uicontrol('style','slide','unit','normalized',...
'position',[0.2 0.15 0.7 0.01],...
'Min',1,'Max',sizej(S.a),'Value', 1,...
'sliderstep',[1/sizej(S.a) 1/sizej(S.a)],'callback', {@SliderCB, 'b', sizej});
% Add a text uicontrol to label the slider.
txtb = uicontrol('Style','text','unit','normalized',...
'position',[0.2 0.16 0.7 0.02],...
'String','Data line ".data(j,:)"');
guidata(S.fh, S); % Store S structure in the figure
end
% Callback for all sliders defined above
function SliderCB(Slider, EventData, Param, sizej)
% S = guidata(Slider); % Get S structure from the figure
% val = round(get(Slider, 'value')); % round slider pos if manually adjusted
% S.(Param) = val; % Any of the 'a', 'b', etc. defined
% update(S); % Update the plot values
% guidata(Slider, S); % Store modified S in figure
%
if Param == 'a'
S = guidata(Slider); % Get S structure from the figure
val = round(get(Slider, 'value')); % round slider pos if manually adjusted
S.(Param) = val; % Any of the 'a', 'b', etc. defined
update(S); % Update the plot values
guidata(Slider, S); % Store modified S in figure
S.bSlider = uicontrol('style','slide','unit','normalized',...
'position',[0.2 0.15 0.7 0.01],...
'Min',1,'Max',sizej(val),'Value', 1,...
'sliderstep',[1/sizej(val) 1/sizej(val)],'callback', {@SliderCB, 'b', sizej});
else
S = guidata(Slider); % Get S structure from the figure
val = round(get(Slider, 'value')); % round slider pos if manually adjusted
S.(Param) = val; % Any of the 'a', 'b', etc. defined
update(S); % Update the plot values
guidata(Slider, S); % Store modified S in figure
end
end
% Plot update, creates new y-vector for plot and replaces the plot
% S.p2 with new y-vector
function update(S)
yset = S.y([S.a,S.b]); % General data set
set(S.p2, 'YData', yset); % Replace old plot with new plotting values
end

6 件のコメント

Alessandro Giacetti
Alessandro Giacetti 2020 年 9 月 18 日
Ok, Thank you very much. Since both the number of the matrix and the number of column are integer, should I change the 'sliderstep' option in the uicontrol command?
Seth Meiselman
Seth Meiselman 2020 年 9 月 18 日
Try it first. Notice that the fake data I created at the top also has integer B and integer M.... all indices are integers in this script.
Rik
Rik 2020 年 9 月 18 日
Why are you ignoring the mlint warning about clear all? You're overwriting all variables that might still exist from a previous run, so even clear isn't strictly necessary.
Seth Meiselman
Seth Meiselman 2020 年 9 月 18 日
Rik- as a stand alone script, I don't want it to interact with any leftovers in the workspace. You can remove those lines if you need to.
Alessandro Giacetti
Alessandro Giacetti 2020 年 9 月 18 日
Rik - Yes of course I removed those lines. I need to use this function inside another one.
Seth - The function works well, now I have a solid base where I might add some useful stuff. I would like to see something that tells me which matrix and which variable the plot show. I am going to work on that. Thank you very much
Rik
Rik 2020 年 9 月 18 日
@Seth, you shouldn't be using 'clear all' in the first place. Use 'clear' or 'clearvars' instead.

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

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeStartup and Shutdown についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by