Tuesday, February 28, 2012

MATLAB: Making a zoom-in plot on top of a plot

Sometimes, it is helpful to provide a zoom-in of a portion of the original plot. While it can be easily done by making them two separate plots using the subplot function, there are times when you wish you can just make the zoom-in plot appear on top of the original plot. The good news is that it is possible, the bad news, well, it requires a work around, since there isn't a nice matlab function which you can simply call to have the job done for you.

The walk around itself is a very simple idea, you can create another axes on top of the original plot and have the zoom-in data copied over to the new axes. If you are doing it for one time only or the plots are very similar, then it may make sense just to hard code everything in and move on. However, in the case where the plots vary quite a bit, a function is probably needed to make it less of a pain.

FUNCTION DESIGN
Input(s):
  ah:  handle of the existing axes
  source_pos: the position of the portion to be zoomed in
  target_pos:  the position where the zoom-in plot will be placed

* To make the function easy to use, the positions as the input variables are based on the axes in the original plot.

Download the zoomPlot.m file from here here and run the following code to see the function in action.


figure; 
t = 0:0.001:0.1;
plot(t, cos(2*pi*50*t)); 
ah = gca; 
% location of the plot to be zoomed in. 
s_pos =[0.05 0 0.06 0.1];
% location of the zoom-in plot 
t_pos = [0.035 0.4 0.065 0.7];    

% generate a zoom-in plot. 
zoomPlot(ah, s_pos, t_pos);     


The resulting plot will look like



So what has been cover in this post is the basic idea of how to get a zoom-in plot to be on top of the original plot. There are many ways to make this basic function more robust and useful.
  • to allow user specify the positions interactively using mouse 
  • to allow user more flexibility in controlling the appearance of the zoom-in axes. 
  • etc. 




Friday, February 24, 2012

MATLAB: How to plot a circle

Ever wonder why there is no circle function when there is a rectangle function?

If you can draw a circle using rectangle function, why would you need a circle function?

The code below plots a circle centered at (x,y), with a radius r, using the rectangle function,

x = 0.5; y = 0.5; r = 0.5;
rectangle('position', [x-r,y-r, 2*r, 2*r], 'Curvature', [1 1]);

The neat thing about using the rectangle function is that you don't need to decide on a 'sampling rate'. The sampling rate is needed if you actually write a function that computes the samples on the circle and plot them as line objects. 



Tuesday, February 21, 2012

MATLAB GUI Inserting background image

Update [2014-04-13]: a function was created for inserting background image to MATLAB gui (or any figure for that matter). It can be found on github.

In many cases, you may wish to insert a background image to the existing GUI. Some of the uicontrols, such as pushbutton and toggle button, have the CData property, which you can set as background using data read from an image (see here). The gui itself, however, does not have such property, and a walk around is needed.

This tutorial shows how you can create an axes in the opening function of the gui and have the background image shown on the axes. To proceed, simply open up an existing gui (or create a new one), and insert the following code in the opening function of the gui.

% create an axes that spans the whole gui
ah = axes('unit', 'normalized', 'position', [0 0 1 1]); 
% import the background image and show it on the axes
bg = imread('example.jpg'); imagesc(bg);
% prevent plotting over the background and turn the axis off
set(ah,'handlevisibility','off','visible','off')
% making sure the background is behind all the other uicontrols
uistack(ah, 'bottom');

Note that the aspect ratio of the gui and the background image should match so that the appearance of the background image is optimized. 

Video walk-through 

MATLAB GUI: implementing drag-and-drop

In the last tutorial, we went over the design of the drag-and-drop functionality of a uicontrol. In this tutorial, we will be implementing the functionality using the code from earlier tutorial. For your convenience, the drag_and_drop function is included in the zip file.

Procedures: 

1. Download mouse5.zip and ready the files in a working matlab directory.
2. Using GUIDE, set WindowButtonMotionFcn, WindowButtonDownFcn, and WindowButtonUpFcn property of the gui to null. You may remove their corresponding functions in the gui_mouse.m file.
3. Attach/register drag_and_drop function to WindowButtonMotionFcn property of the gui in the opening function of the gui.

set(hObject, 'WindowButtonMotionFcn', @drag_and_drop);

4. Save all files and execute the gui.

Video walk-through


Files
Download source code


MATLAB GUI: Designing drag-and-drop interaction

The goal of the series is to design and implement a gui that allows the user to drag and drop an uicontrol in the gui. After all the basic forms of interactions covered in the previous tutorials, we are now ready to design the mouse interactions to meet our specific need.

The mouse has two states, up and down, and has three actions, pressed, moved, and released. However, since you can not press the button when the it is already down, or release the button when it is already up, we are left with only four scenarios to account for (as shown in Table 1 below).

Table 1. Mouse states and actions
State \ Action Pressed Moved Released
Up Pick up the uicontrol Update the pointer N/A
Down N/A Move the uicontrol Drop the uicontrol

Note: when the mouse is moved over a uicontrol, the ButtonDownFcn property of the uicontrol takes over the WindowButtonDownFcn property of the gui, thus, when the mouse is pressed within the uicontrol, ButtonDownFcn is called instead of WindowButtonDownFcn. Moreover, there is a specific set of rules for activating the ButtonDownFcn. It is not as simple as pressing the mouse button within the uicontrol (though, in theory, it should be that simple). For detail of the rules, check here

While it may still look complicated, the design of the drag-and-drop functionality is rather easy, mainly because of the fact that the different functions can be attached to the ButtonDownFcn property of the uicontrol, WindowButtonUpFcn and WindowButtonMotionFcn properties of the gui. Since the the same action can have two different outcomes depending on the state the mouse is in, one has to attach different functions to the properties accordingly. Below, we will go through the design using pseudo code. Note that some of the functions are coded as sub/nested function because they will never be called in any other places.


function drag_and_drop [attached to WindowButtonMotionFcn]
updates the pointer and ButtonDownFcn property as mouse moves in and out of the uicontrol hotspot  

   function grab [attached to ButtonDownFcn]
   updates the pointer to closed-hand shape, attach function drag to WindowButtonMotionFcn and attach function drop to WindowButtonUpFcn as mouse button is pressed 

      function drag [attached to WindowButtonMotionFcn ]  
      updates the object locations 
      end of function drag

      function drop [attached to WindowButtonUpFcn] 
      updates the pointer to hand-shape, re-attach function drag_and_drop to WindowButtonMotionFcn, remove handle to WindowButtonUpFcn. 
      end of function drop 

end of function grab

end of function drag_and_drop

Sunday, February 19, 2012

MATLAB GUI: changing figure pointer

In the fourth part of the series, we look at how to change the figure pointer to a hand shape to indicate the static text can be picked up. Since the hand shape figure pointer is not available in MATLAB, we will be using the setfigptr.m from File Exchange, which has both the hand shape and the closed-hand shape (and many other useful shapes).

Implementation wise, only two lines of code needed to added to the WindowButtonMotionFcn, one line will change the figure pointer to the hand shape when the mouse moves into in the hotspot, while the other line will change the figure pointer to the default pointer when the mouse moves out of the hotspot.

1. Download mouse3.zip and ready the files in a working folder in MATLAB.
2. The setfigptr.m file is included in the zip file. Note that as I am writing this post, the one listed on File Exchange has issues.
3. Open up gui_mouse.m file, go to WindowButtonMotionFcn and copy and paste the following line of code to the corresponding conditional block,

    % change to hand shape pointer     
    setfigptr('hand', handles.fig_mouse);


    % change back to normal arrow pointer 
    setfigptr('arrow', handles.fig_mouse);


4. Save files and run the gui. 


Video walk-through 




Source Files
Download the files here.