Switching values to plot using keyboard input

前端 未结 2 1287
灰色年华
灰色年华 2021-02-06 15:06

I have sets of data in a matrix. I want to plot on set and then use a keyboard input to move to another one. It\'s simply possible this way:

for t=1:N
  plot(dat         


        
相关标签:
2条回答
  • 2021-02-06 15:17

    This demo shows you how to use either the left and right arrows of the keyboard to switch data set or even the mouse wheel.

    It uses the KeyPressFcn and/or WindowScrollWheelFcn event of the figure.

    function h = change_dataset_demo
    
    %// sample data
    nDataset = 8 ;
    x = linspace(0,2*pi,50).' ;     %'// ignore this comment
    data = sin( x*(1:nDataset) ) ;
    
    index.max = nDataset ;
    index.current = 1 ;
    
    %// Plot the first one
    h.fig = figure ;
    h.plot = plot( data(:,index.current) ) ;
    
    %// store data in figure appdata
    setappdata( h.fig , 'data',  data )
    setappdata( h.fig , 'index', index )
    
    %// set the figure event callbacks
    set(h.fig, 'KeyPressFcn', @KeyPressFcn_callback ) ;     %// Set figure KeyPressFcn function
    set(h.fig, 'WindowScrollWheelFcn',@mouseWheelCallback)  %// Set figure Mouse wheel function
    
    guidata( h.fig , h )
    
    
    function mouseWheelCallback(hobj,evt)
        update_display( hobj , evt.VerticalScrollCount )
    
    
    function KeyPressFcn_callback(hobj,evt)
        if ~isempty( evt.Modifier ) ; return ; end  % Bail out if there is a modifier
    
        switch evt.Key
            case 'rightarrow'
                increment = +1 ;
            case 'leftarrow'
                increment = -1 ;
            otherwise
                % do nothing
                return ;
        end
        update_display( hobj , increment )
    
    
    function update_display( hobj , increment )
    
        h = guidata( hobj ) ;
        index = getappdata( h.fig , 'index' ) ;
        data  = getappdata( h.fig , 'data' ) ;
    
        newindex = index.current + increment ;
        %// roll over if we go out of bound
        if newindex > index.max
            newindex = 1 ;
        elseif newindex < 1
            newindex = index.max ;
        end
        set( h.plot , 'YData' , data(:,newindex) ) ;
        index.current = newindex ;
        setappdata( h.fig , 'index', index )
    

    This will roll over when the end of the data set is reached.

    done a little gif too but it's a lot less impressive because it does not show the keyboard/mouse action, only the graph updates :

    animgif

    0 讨论(0)
  • 2021-02-06 15:22

    You can use mouse clicks combined with ginput. What you can do is put your code in a while loop and wait for the user to click somewhere on the screen. ginput pauses until some user input has taken place. This must be done on the figure screen though. When you're done, check to see which key was pushed then act accordingly. Left click would mean that you would plot the next set of data while right click would mean that you plot the previous set of data.

    You'd call ginput this way:

    [x,y,b] = ginput(1);
    

    x and y denote the x and y coordinates of where an action occurred in the figure window and b is the button you pushed. You actually don't need the spatial coordinates and so you can ignore them when you're calling the function.

    The value of 1 gets assigned a left click and the value of 3 gets assigned a right click. Also, escape (on my computer) gets assigned a value of 27. Therefore, you could have a while loop that keeps cycling and plotting things on mouse clicks until you push escape. When escape happens, quit the loop and stop asking for input.

    However, if you want to use arrow keys, on my computer, the value of 28 means left arrow and the value of 29 means right arrow. I'll put comments in the code below if you desire to use arrow keys.

    Do something like this:

    %// Generate random data
    clear all; close all;
    rng(123);
    data = randn(100,10);
    
    %// Show first set of points
    ii = 1;
    figure;
    plot(data(:,ii), 'b.');   
    title('Data set #1');  
    
    %// Until we decide to quit...
    while true 
        %// Get a button from the user
        [~,~,b] = ginput(1);
    
        %// Left click
        %// Use this for left arrow
        %// if b == 28
        if b == 1
            %// Check to make sure we don't go out of bounds
            if ii < size(data,2)
                ii = ii + 1; %// Move to the right
            end                        
        %// Right click
        %// Use this for right arrow
        %// elseif b == 29
        elseif b == 3
            if ii > 1 %// Again check for out of bounds
               ii = ii - 1; %// Move to the left
            end
        %// Check for escape
        elseif b == 27
           break;
        end
    
        %// Plot new data
        plot(data(:, ii), 'b.');
        title(['Data set #' num2str(ii)]);
    end
    

    Here's an animated GIF demonstrating its use:

    enter image description here

    0 讨论(0)
提交回复
热议问题