Update dot in plot according to sliders

2 次查看(过去 30 天)
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

采纳的回答

KevinM
KevinM 2018-5-16
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

更多回答(1 个)

Greg
Greg 2018-5-16
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;

类别

Help CenterFile Exchange 中查找有关 2-D and 3-D Plots 的更多信息

产品


版本

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by