MATLAB is the programming language of choice for many scientists, engineers, and students. In this tutorial, we'll show you how to use it to create rich visualizations of ice thickness, growth, melt and temperature from SIMB3 data.
Before we get started, you'll need:
If you'd like to skip the tutorial and get straight to plotting, you can download the function and file that we build in this tutorial here:
One of the best parts about working with SIMB3 data is that the results are highly visual. With the surface and bottom rangefinder data alone we can see how the ice (and snow!) change thickness through the season. By incorporating data from the vertical temperature string, we can examine the vertical conductive heat flux. If we combine all three measurements, we create a comprehensive picture of the ice state through time that we refer to as a mass balance plot.
A mass balance plot shows ice and snow growth, melt, and internal temperature on a single, easily understandable figure (Figure 1). On the x-axis is time and on the y-axis is thickness or depth. As the ice grows and melts, the distances recorded by the SIMB3 surface and bottom rangefinders lengthen and shorten. With a little knowledge of the SIMB3 dimensions and the deployment conditions, we can turn these distances into ice and snow thickness values. Over time, changes in these values represent ice and snow growth and melt.
In this tutorial, we'll be covering how to make the plot in Figure 1 using MATLAB.
SIMB3 is also equipped with sensors that measure upper-ocean temperature, battery voltage, and meteorological data such as air temperature and barometric pressure. Creating these plots is straightforward compared to the mass balance plot, so we're not going to cover it in this article.
Okay, let's jump right into it. We're going to start by creating a function that takes in data and creates the filled-layer mass balance plot. We'll then create a script file that calls our function, passing it data from the the SIMB3 datasheet.
To create the mass balance plot function, create a new MATLAB file and name it massBalancePlotF.m. Open the file, and paste the following code into it. Don't worry, we'll explain this block-by-block below.
Looking at the function declaration, we see it takes a 2D array of temperature string data (<inlineCode class=matlab>dtc<inlineCode class=matlab>), 1D arrays of surface rangefinder readings (<inlineCode class=matlab>surface_distance<inlineCode class=matlab>), bottom rangefinder readings (<inlineCode class=matlab>bottom_distance<inlineCode class=matlab>), and timestamps (<inlineCode class=matlab>time_stamp<inlineCode class=matlab>). It also takes a scalar values of the deployment snow depth (<inlineCode class=matlab>initial_snow_depth<inlineCode class=matlab>) and the fixed distance between the SIMB3 surface and bottom rangefinders (<inlineCode class=matlab>distance_between_rangefinders<inlineCode class=matlab>).
With exception of the deployment snow depth and the SIMB3 rangefinder distance values, each one of these arrays is taken directly from the labeled column of the SIMB3 datasheet. For a detailed explanation of the SIMB3 datasheet, see Getting started with the SIMB3 datasheet.
In the first block of this function, we take each of our arrays and transpose their rows and columns. This reshapes the 1D arrays into row vectors of length N, where N is the number of entries in the SIMB3 datasheet that we wish to plot For the 2D DTC array, each row represents a reading from one thermistor on the DTC. A column is a collection of DTC readings (192 in total) along the buoy length at one point in time.
We then find the length of our dataset, which we'll use later when creating our filled plots.
In the next block, we create one scalar and two arrays that define the snow height (i.e., the snow thickness) and the ice thickness. The scalar value <inlineCode class=matlab>height_above_ice<inlineCode class=matlab> sets the buoy floatation height (the distance between the surface rangefinder and the ice surface). Here we calculate it as the first surface rangefinder reading plus the snow height at deployment, but it can also be set manually. Often, this value is constant across SIMB3s, but variations in water density (especially between fresh and saltwater ) will cause SIMB3s to float at different heights during deployment and freeze-in.
After the floatation height is established, the time-series array of snow height can be determined. We also calculate ice thickness by subtracting the floatation height and the bottom rangefinder distance from the distance between the surface and bottom rangefinders. For a standard SIMB3, <inlineCode class=matlab>distance_between_rangefinders = 4.051<inlineCode class=matlab> meters.
It should be noted that the "ice thickness" variable name is slightly inaccurate; <inlineCode class=matlab>ice_thickness<inlineCode class=matlab> as computed here is strictly the thickness of ice below freeboard. In the summer, surface melt will contribute to ice thickness reduction that is not captured by this variable.
To plot dates along the x-axis, we need to realign the Excel serial date to the proleptic ISO calendar used by MATLAB (days since 00-Jan-0000). Fortunately, MATLAB has a built-in function that makes this easy.
We then convert our <inlineCode class=matlab>x<inlineCode class=matlab> domain array to a <inlineCode class=matlab>datenum<inlineCode class=matlab>, which we can later convert to a date string when we generate our plots.
Moving along to the third block, we create several variables which define the position of the temperature string relative to the SIMB3 surface rangefinder and ice surface.
The standard SIMB3 Bruncin digital temperature string is 3.84 meters long and measures temperature at 2 cm intervals along the length (192 total values). During buoy manufacturing, the position of the first thermistor is placed 0.2 cm below the surface rangefinder. After installation and freeze-in, this becomes a fixed position above the ice (<inlineCode class=matlab>temp_string_top<inlineCode class=matlab>).
Quick note: the SIMB3sampleDataSheet.csv used in this tutorial was generated by a past-generation SIMB3 which had a <inlineCode class=matlab>temp_string_offset = 0<inlineCode class=matlab>. All modern SIMB3s have a <inlineCode class=matlab>temp_string_offset = 0.2<inlineCode class=matlab>
The temperature string bottom (i.e., the distance between the ice surface and the final thermistor on the chain) is simply the length of the temperature string minus the height of the first thermistor above the ice surface.
As the last step before we can plot the temperature string values, we need to create a vector to represent the vertical spacing of the DTC. To do this, create a vector spanning from <inlineCode class=matlab>temp_string_top<inlineCode class=matlab> to <inlineCode class=matlab>temp_string_bottom<inlineCode class=matlab> with 192 values. Then, create a 2D array of x & y pairs using <inlineCode class=matlab>meshgrid()<inlineCode class=matlab>.
We can then call <inlineCode class=matlab>pcolor()<inlineCode class=matlab>, passing it our 2D arrays X, Y, and DTC as arguments.
MATLAB makes it quite easy to add filled-area regions representing the SIMB3 surface and bottom rangefinder measurements. While there are several ways to do it, we'll do it using the <inlineCode class=matlab>patch()<inlineCode class=matlab> function which creates polygons from lists of x and y coordinates. Note that the first elements in the x and y arguments correspond to the boundary that we want to plot (snow height, ice thickness, etc.) and the second elements correspond to the location that we'd like to plot up or down to.
We can then format the axes and convert the x-axis to a date using <inlineCode class=matlab>datetick()<inlineCode class=matlab>
To call our <inlineCode class=matlab>massBalancePlotF()<inlineCode class=matlab> function, create a new file and name it <inlineCode class=matlab>massBalancePlot.m<inlineCode class=matlab>. Open the file, and add the following code:
In this code, we first import our data sheet using <inlineCode class=matlab>csvread()<inlineCode class=matlab> and a path to our datasheet. We then specify the rows in our datasheet that we want to use to build our mass balance plot.
Note: you'll need to replace the <inlineCode class=matlab>'path/to/your/data/SIMB3sampleDataSheet.csv'<inlineCode class=matlab> with the actual path to the SIMB3 datasheet you'd like to plot. The "1" at the end of <inlineCode class=matlab>csvread()<inlineCode class=matlab> just tells the function to disregard the header.
In the second block, we parse our data array for input to our <inlineCode class=matlab>massBalancePlotF()<inlineCode class=matlab> function. We also define the deployment snow height and the distance between the SIMB3 rangefinders.
Lastly, we call our <inlineCode class=matlab>massBalancePlotF()<inlineCode class=matlab> function and pass it our newly defined arguments.
After running the program, you should see the following plot pop up:
Just like that, we've created a mass balance plot using MATLAB. Additionally, because we created a plotting function, running this for many SIMB3s is as simple as placing it in a loop and feeding it multiple data sheets.
We covered a lot in this tutorial, but I hope you found it useful. If you have any questions or concerns, please reach out and we'll get back to you as soon as we can.
If you don't have access to MATLAB, or if you're more of an open-source kind of person, check out our tutorial on Visualizing SIMB3 data using Python!
What’s a Rich Text element?
BLOCK QUOTE: The rich text element allows you to create and format headings, paragraphs, blockquotes, images, and video all in one place instead of having to add and format them individually. Just double-click and easily create content.
PARAGRAPH: A rich text element can be used with static or dynamic content. For static content, just drop it into any page and begin editing. For dynamic content, add a rich text field to any collection and then connect a rich text element to that field in the settings panel. Voila!
Cameron is the co-founder and CEO of Cryosphere Innovation.