140 likes | 340 Views
Arrays Manipulation and 2D Plots. Generating arrays Array indexing Joining, growing and splitting arrays Review of array-array arithmetic in matlab Functions to manipulate arrays Strings and Cell Arrays Structures More Complex 2D Graphics Basics of handles and get/set. Introduction.
E N D
Arrays Manipulation and 2D Plots • Generating arrays • Array indexing • Joining, growing and splitting arrays • Review of array-array arithmetic in matlab • Functions to manipulate arrays • Strings and Cell Arrays • Structures • More Complex 2D Graphics • Basics of handles and get/set
Introduction Today, we are going to spend most of the day discussing matrices (arrays) and their use in matlab. Although this might not seem like the most fascinating topic, it is crucial that you understand the use and abuse of matrices in matlab. If you understand completely this one topic, you basically understand the bulk of matlab. Before starting, I would like everyone to change their working directory to the Windows Desktop. You can either do this with the cd command, or (easier) by clicking on the “...” besides the “Current Directory” displayed at the top of the Matlab Window and selecting the desktop. We will be saving and loading any and all files from the desktop during these classes.
Generating Matrices Matlab makes it easy to generate simple, useful matrices: • a = ones([5, 1]) % Vector with matrix dimensions • b = zeros( [2, 3, 4] ) • ones( 5 ) % NOTE: short for ones([5 5]),NOT ones([5,1]) • first = 10; last = 20; number = 5; • c = linspace( first, last, number ) % See also logspace • eye( 3 ) % Identity matrix • rand( [ 2, 3 ] ) % Uniform random nums between 0 and 1. • randn( size(a) ) % Random nums with a normal distrib. Note that matlab can quickly generate two types of random numbers. The first generates a number from 0 to 1 with a constant probability for any number between those limits. The second generates a normal or Gaussian distribution of random numbers with mean 0 and variance 1. This second type can be used to generate normal distributions with arbitrary mean and deviation. You can use the size function to get the dimensions of any array. • c = size(b); • [l, w, d] = size(b);
Repeating Matrices Changing the shape or repeating a matrix is also an efficient way to generate useful matrices. Consider the following: • clear all • a = [ 1 4; 2 5; 3 6 ] • aa = reshape( 1:6, [3,2] ) • b = [ 1 2 3; 1 2 3; 1 2 3] • bb = repmat( 1:3, [3, 1] ) Note that a and aa are the same, as are b and bb. reshape takes the matrix given as the first argument (a vector from 1 to 6 in this case) and changes it's dimensions to those given in the second argument. The product of the dimensions must remain the same. repmat takes a matrix and reproduces it the number of times given in the second argument. Play with this function until you are familiar with how it functions. Finally transposing 2D matrices is easy: • a = a'; Note that the transpose operator can be used at any point in a calculation.
Array Indexing Matlab has a wide variety of ways to access and change parts of a matrix. The easiest is with indices: • clear all • a = reshape( 1:20, [4,5] ) • a( 1:2, : ) % Gets first two rows • a( 3:end, : ) % Last three rows • a( 1:2, 1:3 ) • a( [1 3], [1 3 5] ) • a(2) % Single index works as well - rows, then columns • a(:) % Turn it into a column vector end is shorthand for the size of the array in that dimension. : by itself is shorthand for 1:end. Arrays can also be accessed via a boolean array of the same dimension. This is useful for looking at values with certain characteristics. • b = mod(a,2) == 0 % Set of even values in a • a(b) The == operator is NOT for assignment! It tests for equality. Confusing = and == is one of the most common errors in many programming languages.
Changing Arrays The indexing explained in the last slide can be used to modify the contents of an array: • a = reshape( 1:20, [4,5] ); % Repeat from last slide • b = mod(a,2) == 0; % Just in case you didn't do it • a(b) = NaN % Get rid of all even numbers • a • a( isnan(a) ) = -999 Note that some care needs to be taken when using NaN's. Compare the results of the following commands: • 15 == 15 % Returns TRUE (1) • NaN == NaN % Returns FALSE (0) ! • isnan( [1 NaN 3] ) You can also remove entire columns or rows from matrices using the empty matrix. • a(1,:) = [] % Remove first row • a(:,3) = [] % Third column There are also a number of functions useful for testing and indexing matrix contents. See the documentation for all, any and sort.
Joining and Growing Arrays Joining matrices is straightforward in matlab. Follow your nose: • a = reshape( 1:20, [4,5] ); • c = [a, a] % Join along columns • [a; a] • [a, a'] % DOESNT WORK – must have same no. of rows • b = 'abcd'; • [ b 'efgh' ] % Strings are ARRAYS of characters In the last line, I have used the fact that a string is an array to concatenate two strings. Matlab automatically grows matrices if a value is assigned to an index beyond the array size. This is usually useful, but can hide errors. • a(5,5) = 21 % Fills in with 0's • a(:,6) = 1 Growing matrices is computationally intensive. When possible, it is quicker to block off the appropriate amount of memory (array size) from the start and change values as needed.
Array Arithmetic This is something of a review for everyone: • a = reshape( 1:20, [4,5] ); • b = a+a • a * b % DOESNT WORK – bad dimensions • a * b' % Matrix multiplication • a ./ b % Element-by-element division • b .^ a • c = a ~= a(:,end:-1:1) • ~c In matlab, ~is the logical NOT. ~= stands for not-equal (the opposite of ==). Matrix division (/ and \) also exists and is useful for least-squares fitting. There is also a kronecker tensor product (kron). Matlab has all of the typical matrix arithmetic functions. These typically work over columns, but this behavior can be modified: • mean(a) • min(a) • sum(a) • sort(a')
Strings and Cell Arrays Multiple strings can be stored either in character arrays or in cell arrays. Cell arrays are generally easier to use, as will be seen below. • a = [ 'abcd'; 'defg'] % Character arrays with rows • b = { 'abcd', 'defg' } % Cell array • a = [ 'abcd'; 'def' ] %DOESNT WORK – string size changes • b = { 'abcd', 'def' } In many ways cell arrays function the same as normal arrays. They can have multiple dimensions and often be indexed the same as normal arrays. There are however some key differences. • a = {'a', 2, 'c'} • a([2 3]) % Returns a cell array with one element • a{[2 3]} % Returns the number 2. • a{3} = 'Hi' • a(1) = 'Me' % DOESNT WORK – must be cell array • a(1) = { 'Me' } When indexed with (), the result is a cell array; when indexed with {}, the result is called a list. I won't go into detail, but wrap your brain around the following example: • b = {'This', ' stuff', ' sucks.'; 'It', ' is', ' lame'; 'This', ' isn''t', ' cool.' } • [ b{1,:} ] • [ b{ eye(3)>0 } ]
Structures Structures are the last major data type in matlab. They are useful for putting related items together and a particular favorite of mine. • clear all • a.name = 'David' • a.age = 29 • a.height = 'tall' • a.location = [ 38.5, 121.7 ] • a.mom.name = 'Ellen' • a.mom.age = 21 • a • a.mom There are also a series of functions for querying structures: • a = rmfield(a,'height') • isfield(a,'dad') • fieldnames(a) Structures are most commonly used to organize related, but disparate information. It is possible to create arrays of structures and cell arrays that contain structures and structures that contain cell arrays and .....
Plotting 210 There are a number of simple ways to make more interesting plots in matlab. Look at the difference between each of these plots. • a = 0:0.1:3; • plotyy( a, exp(a), a, exp(-a) ) % Two independent axes • semilogy( a, exp(a) ) • loglog(a,exp(a)) You can also put more than one curve on a graph using hold: • plot(a,exp(a)) • hold on • plot(a,exp(-a), 'r-.') • hold off • b = axis % Current axis limits • b(3) = -1; axis(b) % Change axis limits There are a number of specialty plots in matlab that are useful at times. • quiver(a(1:end-1),sin(a(1:end-1)), ... • diff(a),diff(sin(a))) • figure • hist( randn(1,1000), 40) See also feather, compass, plotmatrix and fill.
Handle Graphics Essentially all graphics commands in matlab return a handle upon completion. A handle is a number that can be used at a later time to change the properties of the graphics objects associated with that number. • fh1 = figure • fh2 = figure % Create a second empty figure window • figure(fh1) % Make first active • ph = plot( 1:10, (1:10).^2 ) • figure(fh2) • [n,x] = hist(randn(1,10000)); • bh = bar(x,n,'g') • set(ph,'linewidth',3,'color',[0,1,1]) % RGB color Using the get command you can find out the current state of the object. • get(fh1) • get(bh) set is used to change the state of the object. By itself, set tells you what properties can be changed and their possible values. • set(fh1) • set(fh1,'position',[0 0 560 420]) • set(bh,'edgecolor',[1,0,1],'linewidth',4) See Ch. 31 & the appendix of MM5 for much, much more on handle graphics.
Real-world Example Today we are going to plot up some data of sea-surface currents derived from high-frequency radar installations near Bodega Marine Lab. Links to the necessary files can be found at the end of this page. Save them to the desktop. • open coast.txt; open codar.txt • load coast.txt; load codar.txt Spatial data is in kilometers from a central point, currents are in cm/s. The goal for today is to plot the coast and the nearby current data. First plot the coastline. Make sure to use an “earthy” color. Add a title and axis labels. Use axis equal to fix the aspect ratio. Next, you will need to manipulate the current data so that it is useable. Replace all -999 with NaN's. Perhaps separate the data into good and bad data. Plot a black point where we have current data and a red point where the current data is missing (NaN). Next add in the current vectors using quiver. See the help for scaling vectors. Finally, plot the largest current vector with a different color and a thicker line. To find the largest current vector, you will first need to calculate the total velocity in the normal way and then find the point with the maximum velocity. Consider using ginput and text to add decoration.
Solution • load coast.txt • load currents.txt • ph = plot(coast(:,1),coast(:,2),'color',[0.7,0.3,0.1]) • axis equal • currents(currents == -999) = NaN; • gc = currents( ~any(isnan(currents')), : ); • bc = currents( any(isnan(currents')), : ); • hold on • plot(gc(:,1),gc(:,2),'k.','markersize',12) • plot(bc(:,1),bc(:,2),'r.','markersize',12) • scale = 0.1; • quiver(gc(:,1),gc(:,2),scale * gc(:,3),scale * gc(:,4),0) • tv = sqrt(sum(gc(:,3:4)'.^2)); • top = gc( tv == max(tv), : ); • qh=quiver(top(1),top(2),scale * top(3), scale * top(4), 0); • set(qh,'color','m','linewidth',3)