MATLAB Introduction for Physics of the Earth Students By: Jared Olyphant & Jonathan R. Delph with helpful input from Randy M. Richardson University of Arizona Geophysical Society (UAGS) www.facebook.com/UAGeophysicalSociety Sept. 2 & 4, 2014 Introduction to MATLAB: Part 2 Download material from www.geo.arizona.edu/cdcat/JonathanDelph/UAGS Practice Problem #2: Manipulating 3D datasets within MATLAB Due to its linear algebra language and robust integrated graphics, MATLAB is a powerful tool for manipulating and visualizing 3D data! The following problem aims to introduce you to some of the slightly more advanced plotting and data manipulation tools within MATLAB. As with any programming language, the “plunge” into 3D can boost the complexity quite a bit. However, we hope that by working through this problem you gain some foundational MATLAB knowledge that you can build upon through your own perusing of the help command. For this problem, imagine you went on a hike through the wilderness and collected some x, y, and z (elevation) data using an app on your smartphone. Step 1: Load the text file “prob2_data.txt” into MATLAB. This file contains sparse X-­‐locations, Y-­‐ locations, and Elevation values in columns 1, 2, and 3, respectively (each row represents one data point). For your reference, MATLAB has a ton of different Input/Output (I/O) commands for reading and writing data files. If you are interested, check out the help files for fopen, fscanf, textscan, dlmread, dlmwrite. To make your lives simpler for now, use the load command you used in Problem 1. % First, load in your data; file = load('prob2_data.txt'); Xloc = file(:,1); Yloc = file(:,2); Elev = file(:,3); Step 2: It’s good practice to QC (quality control) your data right away. There are a number of ways to do this, but let’s start by making a simple scatter plot of our data. Type help scatter in the command window and gloss over the first couple paragraphs. I like scatter because it lets you plot data in an X & Y plane, and color your data by another property (for us, this will be elevation). figure(1); % Annotating (1) at the end of 'figure' allows you to come back % to this figure later in your script. scatter(Xloc,Yloc,30,Elev,'o','filled'); colorbar; % 30 = size of markers % 'o' denotes circles % 'filled' fills them % colorbar adds a bar xlabel('X-location (ft)'); ylabel('Y-location (ft)'); title({'Problem 2: Scatter Plot';'Colored by Elevation'}); This should give you an ugly plot that looks like this: Right away you can see that something isn’t right. The majority of your points are ‘blue’ with a few ‘red’ points scattered about. In order to look at your elevation values more closely, you can either double click the ‘Elev’ variable in the MATLAB Workspace, or type Elev in the command window. You’ll notice that scattered throughout the ‘Elev’ vector are some values of 29092, while the rest reside around the ~3000 range. You are pretty certain you didn’t climb to the top of Mount Everest during your adventure, and decide that these data points are erroneous and need to be removed. Step 3: There are numerous ways to accomplish this task, but some methods are more efficient than others. Imagine your dataset is too large for you to manually go through each point and change it, what do you do? Any easy approach is to loop through your data, then use an if statement, and change those 29092 values to NaN. Setting values to NaN tells MATLAB to ignore them for computations and plotting, a valuable trick for data conditioning. for i = 1:length(Elev) if Elev(i) == 29092 Elev(i) = NaN; end end Another approach is to use MATLAB’s find function. Type help find in the command window. The find command tells you the index (i.e. the position of a number within a vector or matrix) at which these values occur. Below is an example on how to use find: row = find(Elev == 29092); Elev(row) = NaN; Create a new figure for your scatter plot to confirm that you removed the bad data points correctly. % Re-plot your data and confirm your max elevation is 3281.55 ft figure(2) scatter(Xloc,Yloc,30,Elev,'o','filled'); colorbar; xlabel('X-location (ft)'); ylabel('Y-location (ft)'); title({'Problem 2: Scatter Plot';'Colored by Elevation'}); Step 4: Right now you think you can see some topographic trends in your data, but you would really like to contour your data to get a better understanding. Unfortunately, with just sparse 2D data you cannot create a contour map. You consult Randy about your predicament, and he waves his hand in the air and rhetorically asks, “Isn’t it obvious? Your data points are perfectly correlated to the following mathematical function:” 𝑋 𝑍 = 3000 + 1000 ∗ −2 ∗𝑒 100 ! ! ! ! ! !! ! !! !"" !"" After convincing Randy that you knew that, you decide to grid your data and compute elevation values at each node with the ultimate goal of generating contour and surface plots. Segue: what does it mean to grid your data? At this point we see from our plots that we have randomly spaced data points in an X-­‐Y plane that spans from 0 to 400 in both X and Y. A grid represents uniformly spaced data points across an area of interest. For our problem, in a visual sense, we want to create something that looks like this: except with elevation values at each node. Step 5: Let’s make the above grid in MATLAB, and then compute elevation values for each (X,Y) node. This is an opportunity to try your hand at nested for-­‐loops, which pop-­‐up a lot in MATLAB modeling. vals = 0:8:400; % create a vector that spans from 0 to 400 in increments of 8 % Use a nested for-loop to create a matrix of X values for each node for j = 1:length(vals) for i = 1:length(vals) X(i,j) = vals(j); end end % % % % % keep column j constant iterate over each row designate X-value close i-loop close j-loop (If the nested for-­‐loop is confusing you, look at the example grid above to help your understanding of the code.) Now you should have a matrix X that contains the value of X at each node. Double-­‐click the variable X in the Workspace and take a few moments to make sure you understand the layout of your new matrix! To get a grid of Y-­‐values, you could repeat the above process, but switch the order of your for-­‐ loops so that you iterate for each column across one row at a time, as opposed to above where we iterated for each row down one column at a time. for i = 1:length(vals) for j = 1:length(vals) Y(i,j) = vals(i); end end % % % % % keep row i constant iterate over each column designate Y-value close j-loop close i-loop Take a look at your Y variable. Does it make sense? You should see that Y is just the transpose of X (not generally true, but true for this problem). If you are too savvy for for-­‐loops, it turns out MATLAB has built in functions for making grids; type help meshgrid to learn more. For our problem, you could create a grid with the simple command: [X,Y] = meshgrid(vals,vals); With our new grid, we can compute elevation values at each point: % Now you have a grid of X & Y points, and you can compute Z at each point: Z = 3000 + ((X./100 - 2).*exp(-(X./100 - 2).^2 - (Y./100 - 2).^2) * 1000); Step 6: Make a contour plot of your X,Y,Z data; type help contour. In general, MATLAB has a lot of idiosyncrasies when it comes to making different types of plots. Use the lines of code below to make your own contour plot, but I strongly recommend reading the help file to better understand how they work. figure(2); hold on; % refer back to figure 2 for plotting [C,h] = contour(X,Y,Z); set(h,'ShowText','on','TextStep',get(h,'LevelStep')*2); % add labels title('Elevation Contours') xlabel('X-location (ft)'); ylabel('Y-location (ft)'); Notice the “ hold on;” command above? This command lets you keep whatever you’ve plotted on the figure, and plot something else on top of it. In this figure, we already had our original data points, now we are adding contours on-­‐top of them. IF you do not use “ hold on” you will lose your original scatter plot, and only plot the contour lines. Finally, let’s make a wireframe mesh plot. Type help mesh in the command window. Just because we can, let’s then plot our original data points on top of the mesh using the plot3 command. figure(3) mesh(X,Y,Z); colorbar; hold on; % mesh does a wireline plot of your data plot3(Xloc,Yloc,Elev,'.','MarkerSize',8); % plot3 allows us to plot our % original datapoints on top of % the new grid. Do they match? Closing Remarks We hope that this tutorial becomes a useful reference for you while you begin to explore MATLAB. The main takeaway is not to memorize all the different functions and plotting commands within MATLAB, but rather to understand the logic behind the language. If you are willing to conform to linear algebra’s rules, you’ll quickly realize how efficiently you can manipulate, index, condition, compute, and ultimately visualize different types of datasets. A (debatably) useful list of key points from this tutorial: 1. MATLAB is really just a calculator with fancy graphics. 2. “for” loops allow you to complete an enormous amount of calculations in microseconds. 3. Along with loops, indexing of vectors and matrices is fundamental. 4. The help command and google are there to help you. Abuse them. 5. MATLAB plotting is much more efficient than Excel once you know some basic commands. 6. If you want to learn how to manipulate plots more, look into the ‘set’ command. 7. Have fun! Email us if you have questions: Jonathan Delph (jrdelph@email.arizona.edu); UAGS President Jared Olyphant (jolyphant@email.arizona.edu); UAGS Vice-­‐President