if <key> is pressed, move <some plotted function> to the right/left
    11 Ansichten (letzte 30 Tage)
  
       Ältere Kommentare anzeigen
    
here is the code:  (the function 'catchkeypress' is below)
    clear; 
    clc; 
    close all;
    xkey=5; 
    save('testp','xkey');       %saves 'xkey' 
    for i=1:100
       load('testp','xkey');    %force script to update the variable 'xkey'
       x=linspace(0,10,1000); 
       y=(x-xkey).^2;
       plot(x,y); 
       axis([0,20, 0,20]); 
       catchKeyPress()          %my function
       pause(0.01)
    end
    and the required function:
    function catchKeyPress
        hkey=figure(1); 
        set(hkey,'KeyPressFcn',@KeyPressCb) ;
        load('testp','xkey');                       %load 'xkey' into function
        function KeyPressCb(~,evnt)                 %?not sure how this works?
            if strcmpi(evnt.Key,'leftarrow')        %left-arrow is pressed
                xkey=xkey-0.01;                     %decrease 'xkey'
                save('testp','xkey'); 
            elseif strcmpi(evnt.Key,'rightarrow')   %right-arrow is pressed
                xkey=xkey+0.01;                     %increase 'xkey'
                save('testp','xkey');               
            end  
        end
     end
---
this code 'works' (y=x.^2 moves to the right if I press the right arrow on my keyboard), 
but I think there is a better way of doing so.
Also, it ONLY works for one variable, 'xkey' in my case, and..
... I can't control how 'much' the figure moves per time I press a button;
... (appearently) I 'have' to save&load the variable 'xkey' in both the script and function for it to work.
What I'm hoping for is something like this:
---
Xoffset=0;
for i=1:n                          %OR while condition
Xoffset=myfunction(Xoffset,RateOfChange); 
y=(x-Xoffset).^2
end
---
in other words, I want to be able to pass the following to 'my' function: 
- wich variable I want to change if I press a key on my keyboard;
- how much it changes if I press it once
and get the 'updated' value as output.
I hope I  explained my problem properly, and any help is welcome
Cheers, 
Luc
0 Kommentare
Antworten (3)
  Nirav Sharda
    
 am 13 Jun. 2017
        This can be achieved using  guidata function which allows to share data between the GUI and callbacks. I have created a small script that you can use as a reference.
% Creating the intial figure data
offset = 0;
x=linspace(0,10,1000); 
y=(x-offset).^2;
f = figure;
% Using guihandles to create the structure in which data can be saved
myhandles = guihandles(f); 
% Adding an offset field to the structure
myhandles.offset = 0;
% Save the structure
guidata(f,myhandles) 
plot(x,y);
% Set the KeyPressFcn Callback
set(f,'KeyPressFcn',{@myfun,1});
function myfun(src,event,rate)
    % Get the structure using guidata in the callback
    myhandles = guidata(src);
    % If right arrow is pressed
    if strcmp(event.Key,'rightarrow')
        %Modify offset in the strucuture with the rate you want
        myhandles.offset = myhandles.offset + rate;
        % Save the change to the structure
        guidata(src,myhandles) 
        % Get the line object which is the grand-child of the figure
        % window
        lineObject = src.Children.Children;
        % Modify the YData of the line object.
        x = lineObject.XData;
        lineObject.YData = (x-myhandles.offset).^2;
    end
end
I have also used the 'KeyPressFcn' callback on the figure window. I hope this helps.
0 Kommentare
  Arnav Mendiratta
    
 am 13 Jun. 2017
        In addition to above answer, you may also achieve this without the use of guidata. The following code updates the frequency of plotted sine wave based on key press.
E.g. Initially, the frequency has been set as 10. If you run the script and press 2, you'll see the frequency of new sine wave to be 20. If you press 9, the new frequency becomes 90.
This is a reference code, I have not implemented any error handling. For example, if you press a character, the frequency becomes 0 and the sine wave disappears.
% set the data for plotting
Fs=1000; %sample rate
dt = 0:1/Fs:1; %time vector
f = 10; %signal frequency
y = sin(2*pi*f*dt); %final signal
% plot the figure and get the figure handle
hFig = figure('KeyPressFcn', @changeFreqOnKeyPress);
figure(hFig); 
hAxs = plot(dt,y);
function changeFreqOnKeyPress(src,event)
    getKey = src.CurrentCharacter;
    newFreqMultiplier = str2double(getKey);
    if ~isempty(newFreqMultiplier)
        newFreq = newFreqMultiplier*10
        src.Children.Children.YData = sin(2*pi*newFreq*src.Children.Children.XData);
    end
end
0 Kommentare
  Steven Lord
    
      
 am 13 Jun. 2017
        What's your goal? Is it to see parts of the function to the right or left of the current "view" in the axes? If so, consider panning your axes instead of using a file-based system for sharing data between callbacks (there are other techniques that will likely work better and/or faster for you) and replotting your data.
0 Kommentare
Siehe auch
Kategorien
				Mehr zu Creating, Deleting, and Querying Graphics Objects finden Sie in Help Center und File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


