Update dot in plot according to sliders

4 Ansichten (letzte 30 Tage)
KevinM
KevinM am 15 Mai 2018
Beantwortet: KevinM am 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

Akzeptierte Antwort

KevinM
KevinM am 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

Weitere Antworten (1)

Greg
Greg am 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;

Kategorien

Mehr zu 2-D and 3-D Plots finden Sie in Help Center und File Exchange

Produkte


Version

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by