# # Drawing

## # Circles

The easiest option to draw a circle, is - obviously - the `rectangle` function.

``````%// radius
r = 2;

%// center
c = [3 3];

pos = [c-r 2*r 2*r];
rectangle('Position',pos,'Curvature',[1 1])
axis equal

``````

but the curvature of the rectangle has to be set to 1!

The `position` vector defines the rectangle, the first two values `x` and `y` are the lower left corner of the rectangle. The last two values define width and height of the rectangle.

``````pos = [ [x y] width height ]

``````

The lower left corner of the circle - yes, this circle has corners, imaginary ones though - is the center `c = [3 3]` minus the radius `r = 2` which is `[x y] = [1 1]`. Width and height are equal to the diameter of the circle, so `width = 2*r; height = width;` In case the smoothness of the above solution is not sufficient, there is no way around using the obvious way of drawing an actual circle by use of trigonometric functions.

``````%// number of points
n = 1000;

%// running variable
t = linspace(0,2*pi,n);

x = c(1) + r*sin(t);
y = c(2) + r*cos(t);

%// draw line
line(x,y)

%// or draw polygon if you want to fill it with color
%// fill(x,y,[1,1,1])
axis equal

`````` ## # Arrows

Firstly, one can use `quiver`, where one doesn't have to deal with unhandy normalized figure units by use of `annotation`

``````drawArrow = @(x,y) quiver( x(1),y(1),x(2)-x(1),y(2)-y(1),0 )

x1 = [10 30];
y1 = [10 30];

drawArrow(x1,y1); hold on

x2 = [25 15];
y2 = [15 25];

drawArrow(x2,y2)

`````` Important is the 5th argument of `quiver`: 0 which disables an otherwise default scaling, as this function is usually used to plot vector fields. (or use the property value pair `'AutoScale','off'`)

``````drawArrow = @(x,y,varargin) quiver( x(1),y(1),x(2)-x(1),y(2)-y(1),0, varargin{:} )
drawArrow(x1,y1); hold on
drawArrow(x2,y2,'linewidth',3,'color','r')

`````` If different arrowheads are desired, one needs to use annotations (this answer is may helpful How do I change the arrow head style in quiver plot?).

The arrow head size can be adjust with the `'MaxHeadSize'` property. It's not consistent unfortunately. The axes limits need to be set afterwards.

``````x1 = [10 30];
y1 = [10 30];

x2 = [25 15];
y2 = [15 25];

xlim([1, 100])
ylim([1, 100])

`````` ``````function [ h ] = drawArrow( x,y,xlimits,ylimits,props )

xlim(xlimits)
ylim(ylimits)

h = annotation('arrow');
set(h,'parent', gca, ...
'position', [x(1),y(1),x(2)-x(1),y(2)-y(1)], ...
props{:} );

end

``````

which you can call from your script as follows:

``````drawArrow(x1,y1,[1, 100],[1, 100],{'Color','b','LineWidth',3}); hold on
drawArrow(x2,y2,[1, 100],[1, 100],{'Color','r','LineWidth',3}); hold on

`````` ## # Ellipse

To plot an ellipse you can use its equation. An ellipse has a major and a minor axis. Also we want to be able to plot the ellipse on different center points. Therefore we write a function whose inputs and outputs are:

``````Inputs:
r1,r2: major and minor axis respectively
C: center of the ellipse (cx,cy)
Output:
[x,y]: points on the circumference of the ellipse

``````

You can use the following function to get the points on an ellipse and then plot those points.

``````function [x,y] = getEllipse(r1,r2,C)
beta = linspace(0,2*pi,100);
x = r1*cos(beta) - r2*sin(beta);
y = r1*cos(beta) + r2*sin(beta);
x = x + C(1,1);
y = y + C(1,2);
end

``````

Exmaple:

``````[x,y] = getEllipse(1,0.3,[2 3]);
plot(x,y);

`````` ## # Polygon(s)

Create vectors to hold the x- and y-locations of vertices, feed these into `patch`.

### # Single Polygon

``````X=rand(1,4); Y=rand(1,4);
h=patch(X,Y,'red');

`````` ### # Multiple Polygons

Each polygon's vertices occupy one column of each of `X`, `Y`.

``````X=rand(4,3); Y=rand(4,3);
for i=2:3
X(:,i)=X(:,i)+(i-1); % create horizontal offsets for visibility
end

h=patch(X,Y,'red');

`````` ## # Pseudo 4D plot

A `(m x n)` matrix can be representes by a surface by using surf;

The color of the surface is automatically set as function of the values in the `(m x n)` matrix. If the colormap is not specified, the default one is applied.

A colorbar can be added to display the current colormap and indicate the mapping of data values into the colormap.

In the following example, the `z (m x n)` matrix is generated by the function:

``````z=x.*y.*sin(x).*cos(y);

``````

over the interval `[-pi,pi]`. The `x` and `y` values can be generated using the meshgrid function and the surface is rendered as follows:

``````% Create a Figure
figure
% Generate the `x` and `y` values in the interval `[-pi,pi]`
[x,y] = meshgrid([-pi:.2:pi],[-pi:.2:pi]);
% Evaluate the function over the selected interval
z=x.*y.*sin(x).*cos(y);
% Use surf to plot the surface
S=surf(x,y,z);
xlabel('X Axis');
ylabel('Y Axis');
zlabel('Z Axis');
grid minor
colormap('hot')
colorbar

`````` Figure 1

Now it could be the case that additional information are linked to the values of the `z` matrix and they are store in another `(m x n)` matrix

It is possible to add these additional information on the plot by modifying the way the surface is colored.

This will allows having kinda of 4D plot: to the 3D representation of the surface generated by the first `(m x n)` matrix, the fourth dimension will be represented by the data contained in the second `(m x n)` matrix.

It is possible to create such a plot by calling `surf` with 4 input:

``````surf(x,y,z,C)

``````

where the `C` parameter is the second matrix (which has to be of the same size of `z`) and is used to define the color of the surface.

In the following example, the `C` matrix is generated by the function:

``````C=10*sin(0.5*(x.^2.+y.^2))*33;

``````

over the interval `[-pi,pi]`

The surface generated by `C` is Figure 2

Now we can call `surf` with four input:

``````figure
surf(x,y,z,C)
xlabel('X Axis');
ylabel('Y Axis');
zlabel('Z Axis');
grid minor
colormap('hot')
colorbar

`````` Figure 3

Comparing Figure 1 and Figure 3, we can notice that:

• the shape of the surface corresponds to the `z` values (the first `(m x n)` matrix)
• the colour of the surface (and its range, given by the colorbar) corresponds to the `C` values (the first `(m x n)` matrix) Figure 4

Of course, it is possible to swap `z` and `C` in the plot to have the shape of the surface given by the `C` matrix and the color given by the `z` matrix:

``````figure
surf(x,y,C,z)
xlabel('X Axis');
ylabel('Y Axis');
zlabel('Z Axis');
grid minor
colormap('hot')
colorbar

``````

and to compare Figure 2 with Figure 4 ## # Fast drawing

There are three main ways to do sequential plot or animations: `plot(x,y)`, `set(h , 'XData' , y, 'YData' , y)` and `animatedline`. If you want your animation to be smooth, you need efficient drawing, and the three methods are not equivalent.

``````% Plot a sin with increasing phase shift in 500 steps
x = linspace(0 , 2*pi , 100);

figure
tic
for thetha = linspace(0 , 10*pi , 500)
y = sin(x + thetha);
plot(x,y)
drawnow
end
toc

``````

I get `5.278172 seconds`. The plot function basically deletes and recreates the line object each time. A more efficient way to update a plot is to use the `XData` and `YData` properties of the `Line` object.

``````tic
h = [];   % Handle of line object
for thetha = linspace(0 , 10*pi , 500)
y = sin(x + thetha);

if isempty(h)
% If Line still does not exist, create it
h = plot(x,y);
else
% If Line exists, update it
set(h , 'YData' , y)
end
drawnow
end
toc

``````

Now I get `2.741996 seconds`, much better!

`animatedline` is a relatively new function, introduced in 2014b. Let's see how it fares:

``````tic
h = animatedline;
for thetha = linspace(0 , 10*pi , 500)
y = sin(x + thetha);
clearpoints(h)
`3.360569 seconds`, not as good as updating an existing plot, but still better than `plot(x,y)`.
Of course, if you have to plot a single line, like in this example, the three methods are almost equivalent and give smooth animations. But if you have more complex plots, updating existing `Line` objects will make a difference.