Update dot in plot according to sliders

5 vues (au cours des 30 derniers jours)
KevinM
KevinM le 15 Mai 2018
Réponse apportée : KevinM le 16 Mai 2018
As stated in the question, I'm trying to draw a dot along a plotted graph. The graph is simulating the normalized throughput of the SAW-ARQ and it depends on 3 variables, which can be changed with 1 slider each. The dot should represent the result of the equation with the given parameters (from the sliders).
So far, I have managed to obtain the values from the sliders with a listener, but when I try to draw it within the callback of the listener, the old positions of the dot are not removed (as can be seen in the screenshot).
I want the graph to have the constant line, which doesn't have to do anything with the sliders and a dot, which is on the position according to the slider values. This dot should basically overwrite the old dot on the new position, so only 1 dot at a time.
I have also tried using the set command within the callback, but it returned an error, so I thought this was the easier way.
You can find my code below:
clear all; close all;
a = logspace(-1,3);
p = zeros(1,50);
% calculation with given a
for i = 1:length(a)
S(i) = calcS(a(i),p(i));
end
f = figure;
semilogx(a,S); hold on;
title('SAW-ARQ performance');
% xlabel({'a','increasing data rate \rightarrow','increasing distance \rightarrow','\leftarrow increasing PDU size'});
xlabel({'a','','','','',''});
ylabel('normalized throughput'); grid on;
sliderControl(f);
% d ... distance; v ... velocity/speed; L ... PDU length; R ... data rate
function a = calcA(d,v,L,R)
a = (d/v)/(L/R);
end
% p ... error probability
function S = calcS(a,p)
S = (1-p)/(1+2*a);
end
function [] = sliderControl(f)
guidata(f,struct('d',1000,'dr',64000,'pdu',1000));
% Distance
sliderDistance = uicontrol('Parent',f,'Style','slider','Position',[160,60,360,23],...
'String','distance','value',1000,'min',0,'max',10e6);
uicontrol('Parent',f,'Style','text','Position',[10,56,140,23],...
'String','Distance [0m...1000km]','BackgroundColor',f.Color);
addlistener(sliderDistance,'ContinuousValueChange',@updateGraph);
% Data rate
sliderDataRate = uicontrol('Parent',f,'Style','slider','Position',[160,35,360,23],...
'String','datarate','value',64000,'min',0,'max',10e8);
uicontrol('Parent',f,'Style','text','Position',[10,31,140,23],...
'String','Data rate [0bit/s...1Gbit/s]','BackgroundColor',f.Color);
addlistener(sliderDataRate,'ContinuousValueChange',@updateGraph);
% PDU size
sliderPDU = uicontrol('Parent',f,'Style','slider','Position',[160,10,360,23],...
'String','pdu','value',1000,'min',0,'max',1500);
uicontrol('Parent',f,'Style','text','Position',[10,6,140,23],...
'String','PDU length [0bit...1500bit]','BackgroundColor',f.Color);
addlistener(sliderPDU,'ContinuousValueChange',@updateGraph);
end
function [] = updateGraph(varargin)
hObj = varargin{1};
data = guidata(hObj);
if strcmp(get(hObj,'String'),'distance')
% d = get(hObj,'Value');
data.d = hObj.Value;
guidata(hObj,data);
elseif strcmp(get(hObj,'String'),'datarate')
% dr = get(hObj,'Value');
data.dr = hObj.Value;
guidata(hObj,data);
else
% pdu = get(hObj,'Value');
data.pdu = hObj.Value;
guidata(hObj,data);
end
% Calculation
a = logspace(-1,3);
tempA = calcA(data.d,3e8,data.pdu,data.dr);
tempS = calcS(tempA,0.00);
if tempA > a(1) && tempA < a(length(a))
plot(tempA,tempS,'or','MarkerSize',5,'MarkerFaceColor','r');
pause(.5);
end
end

Réponse acceptée

KevinM
KevinM le 16 Mai 2018
I managed to solve the problem by myself, inspired by your answer.
Here is what I did:
  • Create an empty plot with handle for the dot after the line plot
dotPlot = plot(NaN,NaN,'or','MarkerSize',5,'MarkerFaceColor','r');
  • Change the callback-method for all 3 listeners so they have a third parameter for the plot
addlistener(sliderDistance,'ContinuousValueChange',@(src,evnt)updateGraph(src,evnt,dotPlot));
  • Use set to update the dot according to the sliders in the callback
% Calculation
a = logspace(-1,3);
tempA = calcA(data.d,3e8,data.pdu,data.dr);
tempS = calcS(tempA,0.00);
if tempA > a(1) && tempA < a(length(a))
set(dotPlot,'XData',tempA,'YData',tempS);
pause(.2);
end

Plus de réponses (1)

Greg
Greg le 16 Mai 2018
I forget which release introduced MarkerIndices for plots, but I think that's exactly what you're going for. You don't need an additional plot when using MarkerIndices. Store the handle from the original plot, then just update inside your slider callback:
% Code to calculate plotted array indices to receive markers
newIndices = ...
hPlot.MarkerIndices = newIndices;

Catégories

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

Produits


Version

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by