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

15 vues (au cours des 30 derniers jours)
Alessandro Giacetti
Alessandro Giacetti le 4 Août 2020
Commenté : Rik le 18 Sep 2020
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 commentaires
Alessandro Giacetti
Alessandro Giacetti le 17 Sep 2020
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 le 17 Sep 2020
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.

Connectez-vous pour commenter.

Réponse acceptée

Seth Meiselman
Seth Meiselman le 18 Sep 2020
Modifié(e) : Seth Meiselman le 18 Sep 2020
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 commentaires
Alessandro Giacetti
Alessandro Giacetti le 18 Sep 2020
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 le 18 Sep 2020
@Seth, you shouldn't be using 'clear all' in the first place. Use 'clear' or 'clearvars' instead.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur 2-D and 3-D Plots dans Help Center et File Exchange

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by