Lab 1.7 Basic sample descriptors; Tinkering with Plots

Introduction

In the last 2 labs, we have learned the concepts underlying basic statistical tests, and learned how to perform a few basic statistical procedures: we learned to test whether 2 samples are likely to be derived from the same true distributions (Kolmogorov-Smirnov test), how to establish confidence intervals around the mean (central limit theorem), and how to examine whether the means of 2 normal-ish distributions are the same or different (T-test of 2 samples).

In today's lab, we will focus more deeply on understanding common descriptors that are used with sampled data. In the second half of the lab, we'll have some fun learning more about Matlab's plotting and graphics environment.

In Lab 1.5, we saw that the process of statistical inference involved sampling from a "true" distribution that we can never know exactly, and then making inferences about the true population based on the sample. Here, we will discuss some basic descriptors of distributions, and how they are related to one another.

Measures of variation / deviation

Just about any phenomenon that we would want to study exhibits variation. (If there were no variation, then there would be nothing to study, really.) It's important to recognize that there are many sources of variation.

Let's imagine a variable like "height of people in the world who are older than 25 years of age". Everyone in the world is not equally tall. Due to genetic and environmental factors both known and unknown to science, height varies from person to person.

One could imagine documenting this variation in a number of ways, some of which we've already seen. We've looked at percentiles, histograms, and, my favorite, the cumulative histogram, which allows one to read off the entire structure of a whole distribution by examining all percentiles of the data.

The most commonly reported single measures of variation are the variance and its companion measure, the standard deviation. The variance and standard deviation measure of how each value of a distribution deviates from the mean.

Recall that the mean (represented by P with a bar over it) is just the numerical average of all values of the population (enumerated by P1, P2, P3, ... PM, where M is the total number of members of the population).

The variance is the average squared deviation of each point from the mean, and the standard deviation is just the square root of the variance:

Note that the variance has the units of the population value squared. So, in our example of heights of the world, the variance has the units of meters2, whereas the standard deviation has the same units as the population value (in this case, meters).

You may ask yourself, why is the square of these deviations something useful to compute? Why not calculate the absolute value of the difference between each sample and the mean, or the cube...why do people do this? There are several reasons, but one is that many variables in nature and in mathematics are Normally distributed, and a Normally-distributed variable (that is, one that follows the Normal distribution we saw in Lab 1.6) can be described completely by its mean and variance/standard deviation. When we turn to fitting a few labs down the road, we'll see another advantage to using the squared difference.

Inferring the mean and standard deviation of the "true" distribution from a sample

Suppose we have a sample of real data points that we'll call S, and we'll call the individual sample points S1, S2, ... Sn. ; then it is entirely possible to calculate the mean and standard deviation from the sample data points. To indicate that the source of these values are different from the "true" population in the equations above, we'll calculate analogous quantities with different names.

There is the sample mean S bar (S with a bar over it), the sample variance (s2), and sample standard deviation (s):

But, most of the time we actually want to infer the mean and standard deviation of the true distribution from which the samples are derived. S bar is once again the estimate of the mean of the true distribution, but, amazingly, the equation for the estimate of the "true" distribution variance/standard deviation is slightly different:

What is the reason for the difference? Why do we divide by N-1 instead of N to estimate the variance of the true distribution/population? The explanation is a little mathy, but if you're interested, it's right here. The short short version is that there is some uncertainty in the "true" mean that is unaccounted for by dividing by N (that's not really an explanation).

With an estimate of the sample standard deviation in hand, we can estimate the standard error of the mean, which we saw in the last lab allows us to estimate confidence intervals around the sample mean (that is, it answers how much we expect the sample mean to deviate from the population mean):

Recall that the procedure of sampling produces an estimate of the true mean that is normally distributed with variance equal to the standard error of the mean. This means that there is a 68% chance that the true mean is within SE of the sample mean, and a 95% chance that the true mean is within 2*SE of the sample mean.

Here's a table summary of these quantities:


For your study, do you want to report the full distribution or the mean and standard error?

Many papers report only the mean and standard error of their experiments. Let's look at how this is done. Let's use the example chicken weights from animals that were fed normal corn or lysin-enriched corn from the PS1_2.zip file.

chicken_weights = load('chickenweights_control_experimental.txt','-ascii');

chicken_control = chicken_weights(:,1); % grab the first column

chicken_exper = chicken_weights(:,2); % grab the 2nd column

mn1 = mean(chicken_control);

mn2 = mean(chicken_exper);

If we wanted to report this data, we could plot the entire distribution:

figure;

bar(1,mn1,'w');

hold on;

bar(2,mn2,'w');

plot(1,chicken_control,'go');

plot(2,chicken_exper,'rs');

xlabel('Groups');

ylabel('Weight');

title('Chicken weights after normal feed (left) or enriched feed (right)');

or we could simply plot the mean and standard error (using the std function in Matlab, which computes the estimate of the true distribution standard deviation, Ĺť, as above):

figure;

se_control = std(chicken_control)/sqrt(length(chicken_control));

se_enriched = std(chicken_exper)/sqrt(length(chicken_exper));

bar(1,mn1,'w');

hold on;

bar(2,mn2,'w');

plot([1 1],[mn1-se_control mn1+se_control],'k-');

plot([2 2],[mn2-se_enriched mn2+se_enriched],'k-');

xlabel('Groups');

ylabel('Weight');

title('Chicken weights after normal feed (left) or enriched feed (right)');

Q1: Which plot do you like better for this data? Which do you think tells you the most about the experiment?

Sources of variation / deviation

Variation in actual experiments has many sources. First, there is the variation in the underlying true distribution itself. Second, we are sampling, so there is some inherent uncertainty in our knowledge of the true distribution. Third, there may be noise in the measurements that we are able to make due to our instrumentation or other factors.

Suppose the measurements of chicken weights were very noisy, such that the measurements were Normally distributed with a standard deviation of 100 grams (wiggly chickens, for instance). We can simulate this situation by adding noise to the data above. The function randn generates pseudorandom noise (see help randn).

randn(1,2) % 1x2 set of random values with mean 0 and standard deviation 1

5*randn(1,2) % 1x2 set of random values with mean 0 and standard deviation 5

You can verify the mean and standard deviation of the noise produced by the randn function:

std(5*randn(1000,1)) % standard deviation of 1000 random points

mean(5*randn(1000,1)) % mean of 1000 random points

In this simulation, we'd like to generate a set of random values that is the same size as our experimental data. To do this, we can use the function size (see help size).

size(chicken_exper)

Now we can create our simulated data:

chicken_exper2 = chicken_exper + 50*randn(size(chicken_exper));

chicken_control2 = chicken_control + 50*randn(size(chicken_control));

mn1_2 = mean(chicken_control2);

mn2_2 = mean(chicken_exper2);

figure;

bar(1,mn1_2,'w');

hold on;

bar(2,mn2_2,'w');

plot(1,chicken_control2,'go');

plot(2,chicken_exper2,'rs');

xlabel('Groups');

ylabel('Weight');

title('Noisy weights after normal feed (left) or enriched feed (right)');

figure;

se_control2 = std(chicken_control2)/sqrt(length(chicken_control2));

se_enriched2 = std(chicken_exper2)/sqrt(length(chicken_exper2));

bar(1,mn1_2,'w');

hold on;

bar(2,mn2_2,'w');

plot([1 1],[mn1_2-se_control2 mn1_2+se_control2],'k-');

plot([2 2],[mn2_2-se_enriched2 mn2_2+se_enriched2],'k-');

xlabel('Groups');

ylabel('Weight');

title('Noisy weights after normal feed (left) or enriched feed (right)');

Q2: Does knowing that the level of pure measurement noise in this new sample is large have an impact on your opinion of which graph is more informative?

Q3: To what can we attribute variation in a sample? Of the things you mention, is it always possible to know how much each one contributes to the variation in the sample?

Tinkering with plots

In the last 2 labs and in the homework, we have created several plots. Matlab offers a lot of flexibility for customizing these plots. In this section, we will explore the data structures that underlie Matlab plots and show you how to edit their fields from the command line.

Please make sure you have the correct histbins.m file, and then let's generate some data for plotting:

mydata1 = 100*dasw.stats.generate_random_data(100,'normal',1,1);

[N,bin_centers] = dasw.plot.histbins(mydata1,[-500:100:500]);

f = figure;

bar(bin_centers,N);

xlabel('X');

ylabel('Y');

We can get the properties of the figure we just made using the get command:

get(f)

You will see a number of property name and value pairs displayed on the screen. I get the following (you can skim these; no need to read them in depth, but do notice there are a lot of properties that have values):

'Figure' property fields

Alphamap = [ (1 by 64) double array]

CloseRequestFcn = closereq

Color = [0.8 0.8 0.8]

Colormap = [ (64 by 3) double array]

CurrentAxes = [341.002]

CurrentCharacter =

CurrentObject = [341.002]

CurrentPoint = [482 395]

DockControls = on

FileName =

IntegerHandle = on

InvertHardcopy = on

KeyPressFcn =

KeyReleaseFcn =

MenuBar = figure

Name =

NextPlot = add

NumberTitle = on

PaperUnits = inches

PaperOrientation = portrait

PaperPosition = [0.25 2.5 8 6]

PaperPositionMode = manual

PaperSize = [8.5 11]

PaperType = usletter

Pointer = arrow

PointerShapeCData = [ (16 by 16) double array]

PointerShapeHotSpot = [1 1]

Position = [680 494 560 420]

Renderer = painters

RendererMode = auto

Resize = on

ResizeFcn =

SelectionType = normal

ToolBar = auto

Units = pixels

WindowButtonDownFcn =

WindowButtonMotionFcn =

WindowButtonUpFcn =

WindowKeyPressFcn =

WindowKeyReleaseFcn =

WindowScrollWheelFcn =

WindowStyle = normal

XDisplay = /tmp/launch-iH0FBE/org.x:0

XVisual = 0x24 (TrueColor, depth 24, RGB mask 0xff0000 0xff00 0x00ff)

XVisualMode = auto

BeingDeleted = off

ButtonDownFcn =

Children = [341.002]

Clipping = on

CreateFcn =

DeleteFcn =

BusyAction = queue

HandleVisibility = on

HitTest = on

Interruptible = on

Parent = [0]

Selected = off

SelectionHighlight = on

Tag =

Type = figure

UIContextMenu = []

UserData = []

Visible = on

We can modify the parameters of these fields with the set command:

set(f,'Color',[1 0 0]); % changes the background color to red

set(f,'MenuBar','none'); % turns off the menu bar

Handles

The variable f is called a handle to the figure. Its value, (a whole number for figures), is essentially a common reference number that the user and Matlab can use to refer to the figure. Each graphics object in Matlab, like figures and sets of plotting axes, has a unique handle number.

We can use the function gcf ("get current figure") to return the handle to the frontmost figure. This is a good way to obtain the handle for a figure if you don't know it (or if your program doesn't know it):

f = gcf

One can access the objects that are part of the figure by examining the figure's children field:

objects = get(f,'children')

In this case, the figure has 1 object, which corresponds to the plotting axes on the figure. We can also access the current plotting axes with the function gca ("get current axes"):

ax = gca

We can look at the properties of axes as follows:

get(ax)

On my system, I see a long list of properties (you can skim them, no need to read them in depth):

'Axes' property fields

ActivePositionProperty = outerposition

ALim = [0 1]

ALimMode = auto

AmbientLightColor = [1 1 1]

Box = on

CameraPosition = [0 20 17.3205]

CameraPositionMode = auto

CameraTarget = [0 20 0]

CameraTargetMode = auto

CameraUpVector = [0 1 0]

CameraUpVectorMode = auto

CameraViewAngle = [6.60861]

CameraViewAngleMode = auto

CLim = [1 2]

CLimMode = auto

Color = [1 1 1]

CurrentPoint = [ (2 by 3) double array]

ColorOrder = [ (7 by 3) double array]

DataAspectRatio = [500 20 1]

DataAspectRatioMode = auto

DrawMode = normal

FontAngle = normal

FontName = Helvetica

FontSize = [10]

FontUnits = points

FontWeight = normal

GridLineStyle = :

Layer = bottom

LineStyleOrder = -

LineWidth = [0.5]

MinorGridLineStyle = :

NextPlot = replace

OuterPosition = [0 0 1 1]

PlotBoxAspectRatio = [1 1 1]

PlotBoxAspectRatioMode = auto

Projection = orthographic

Position = [0.13 0.11 0.775 0.815]

TickLength = [0.01 0.025]

TickDir = in

TickDirMode = auto

TightInset = [0.0767857 0.0904762 0.00357143 0.0190476]

Title = [347.002]

Units = normalized

View = [0 90]

XColor = [0 0 0]

XDir = normal

XGrid = off

XLabel = [345.002]

XAxisLocation = bottom

XLim = [-500 500]

XLimMode = auto

XMinorGrid = off

XMinorTick = off

XScale = linear

XTick = [-450 -350 -250 -150 -50 50 150 250 350 450]

XTickLabel =

-450

-350

-250

-150

-50

50

150

250

350

450

XTickLabelMode = auto

XTickMode = manual

YColor = [0 0 0]

YDir = normal

YGrid = off

YLabel = [346.002]

YAxisLocation = left

YLim = [0 40]

YLimMode = auto

YMinorGrid = off

YMinorTick = off

YScale = linear

YTick = [0 5 10 15 20 25 30 35 40]

YTickLabel =

0

5

10

15

20

25

30

35

40

YTickLabelMode = auto

YTickMode = auto

ZColor = [0 0 0]

ZDir = normal

ZGrid = off

ZLabel = [348.002]

ZLim = [-1 1]

ZLimMode = auto

ZMinorGrid = off

ZMinorTick = off

ZScale = linear

ZTick = [-1 0 1]

ZTickLabel =

ZTickLabelMode = auto

ZTickMode = auto

BeingDeleted = off

ButtonDownFcn =

Children = [342.005]

Clipping = on

CreateFcn =

DeleteFcn =

BusyAction = queue

HandleVisibility = on

HitTest = on

Interruptible = on

Parent = [2]

Selected = off

SelectionHighlight = on

Tag =

Type = axes

UIContextMenu = []

UserData = []

Visible = on

We can adjust a number of properties of the axes using the handle.

axis([-500 500 0 50]);

set(ax,'YTick', [0 50]);

set(ax,'YDir','reverse');

set(ax,'YDir','normal');

Q4: What happened to the plot after you ran these 4 statements?

One sad fact of Matlab is that these properties and what they control are not very well documented. Most of what I have learned has come from trying different things and seeing what happens. Recently, Matlab has added a feature to set that gives a little feedback on what values some properties can take. If you call set with no property value, it returns a list of possible values (but only for properties that can take discrete values; some properties take continuous values, and you're out of luck). For example:

set(ax,'YDir')

Q5: What values can the axes property YDir take?

Our set of axes also has children; the children correspond to the items that are plotted on the axes. In this case, we currently only have the bar plot:

ch = get(ax,'children')

get(ch)

The properties of a bar plot are as follows on my system:

'Bar plot' property fields

Annotation: [1x1 hg.Annotation]

DisplayName: ''

HitTestArea: 'off'

BeingDeleted: 'off'

ButtonDownFcn: []

Children: 343.0017

Clipping: 'on'

CreateFcn: []

DeleteFcn: []

BusyAction: 'queue'

HandleVisibility: 'on'

HitTest: 'on'

Interruptible: 'on'

Parent: 341.0017

SelectionHighlight: 'on'

Tag: ''

Type: 'hggroup'

UIContextMenu: []

UserData: []

Selected: 'off'

Visible: 'on'

XData: [-450 -350 -250 -150 -50 50 150 250 350 450]

XDataMode: 'manual'

XDataSource: ''

YData: [0 0 0 2 13 40 31 9 4 1]

YDataSource: ''

BaseValue: 0

BaseLine: 344.0017

BarLayout: 'grouped'

BarWidth: 0.8000

Horizontal: 'off'

LineWidth: 0.5000

EdgeColor: [0 0 0]

FaceColor: 'flat'

LineStyle: '-'

ShowBaseLine: 'on'

We can play with these fields as well:

mybar = ch; % so we don't have to keep referring to ch

set(mybar,'barwidth',1); % what happens?

set(mybar,'barwidth',0.5);

set(mybar,'facecolor',[1 0 0]); % turn it red

set(mybar,'facecolor',[0 0 0]); % paint it black

The general idea of examining a graphic object's handle for its field values, and then examining its children for their field values, is very helpful for creating customized plots that highlight exactly what you want to show.

One can also delete handles using the delete function (but be careful; if you give delete a string input like 'myfile', it will assume you are passing a filename you want to delete):

delete(mybar);

delete(ax);

delete(f);

Multiple axes per figure

Matlab also has routines that help you to arrange more than one set of axes on a figure at a time. The easiest way to do this is with the subplot function. For example:

mydata1 = 100*dasw.stats.generate_random_data(100,'normal',1,1);

mydata2 = 100*dasw.stats.generate_random_data(100,'normal',1,1);

[X1,Y1] = dasw.plot.cumhist(mydata1);

[X2,Y2] = dasw.plot.cumhist(mydata2);

f = figure;

[N1,bin_centers] = dasw.plot.histbins(mydata1,[-600:100:600]);

[N2,bin_centers] = dasw.plot.histbins(mydata2,[-600:100:600]);

ax1=subplot(2,2,1);

plot(X1,Y1,'k-');

axis([-600 600 0 100]);

xlabel('Value');

ylabel('Fraction of data 1');

ax2=subplot(2,2,2);

plot(X2,Y2,'k-');

axis([-600 600 0 100]);

xlabel('Value');

ylabel('Fraction of data 2');

ax3=subplot(2,2,3);

bar(bin_centers,N1,'k');

xlabel('Value');

ylabel('Number of data 1 points');

ax4=subplot(2,2,4);

bar(bin_centers,N2,'k');

xlabel('Value');

ylabel('Number of data 2 points');

subplot takes 3 input arguments: the number of rows of axes you want, the number of columns of axes you want, and the axes number it should create (numbered left to right, top to bottom; see help subplot). In this case, we defined a 2 row by 2 column matrix of axes, and plotted a graph in each one.

Q6: How many children do you think the figure has now?

ch = get(f,'children')

Q7: Are they the axes that were created by the subplot calls?

ax1,

ax2,

ax3,

ax4

Function reference

Matlab functions and operators

User functions

  • [no new functions]

Copyright 2011-2012 Stephen D. Van Hooser, all rights reserved.