Visualizing your solutions with Mathematica

Comp 110 Module 5

A common saying is that "A picture is worth a thousand words."  In Mathematica, this saying is especially true.  Consider the following function

f[x_]:=Sin[(1/x)]

How does the function f[x] behave as x approaches zero?  One way to investigate the behavior of this function is to make a Table of its values as x varies between -1 and 1.

fList=Table[f[x],{x,-1,1,.01}]

Unfortunately, this table of numbers doesn't provide much insight.  Of course, the solution to our problem is to make a picture (visualize) of the behavior of f[x] at x=0.

Plot[f[x],{x,-1,1}]

Based on this plot, it is clear that f[x] oscillates sinusoidally with increasing frequency as x->0.

For most of the problems that you will consider in the rest of this class, solving the problem will be only part of your task.  An equally important part will be to visualize your solution in way that conveys the meaning of your solution.  In this module, we will review some of the graphical tools that Mathematica provides for building visualizations.

Mathematica's built-in plotting functions

Mathematica partitions its built-in functions for visualization based on the type of information in the object being visualized.  If the object depends on a continuous range of values, Mathematica uses function visualization;  if the object consists of a discrete set of data, Mathematica uses visualization based on lists.

Visualization of functions

Mathematica supports a number of methods for visualizing functions, depending on the number of parameters that the functions take.  The Mathematica tutorial Function Visualization gives a succinct overview of the various functions that are available.  For our purposes, we will concentrate on five functions.

If we wish to visualize a function of one variable, the Mathematica function Plot is simple and easy to interpret. For example

g[x_]:=(1/((x^2)+.001))

Plot[g[x],{x,-1,1}]

Note that in this particular plot, Mathematica has detected that the range of output values of g[x] is widely varying and automatically restricts the range (the y coordinates) to values from 0 to 70.  If you are unhappy with this choice, Mathematica provides a number of options that allow you to control the style of the output.  These options have the form Option->Value.  In our previous example, we can added PlotRange->All and force Mathematica to plot the entire range of values for g[x].

Plot[g[x],{x,-1,1},PlotRange->All]

Spend a couple of minutes browsing Mathematica's tutorial on Options & Styling to get a better feel for Mathematica's capabilities.

For functions of two variables, Mathematica provides three functions that provide reasonable visualizations.  As a test function, let's consider the function

h[x_,y_]:=Sin[x]Sin[y]

The simplest way to visualize h[x,y] is as a height surface drawn in 3D using the function Plot3D.

Plot3D[h[x,y],{x,0,2π},{y,0,2π}]

Note that this surface is a graphical object in 3D and can be rotated in 3D by simply clicking and dragging the object.

An alternative way to visualize the behavior of this function is to draw the contours of the function.  A contour is the set of all points {x,y} such that h[x,y]==c, where c is a constant. Contour lines are a standard method for visualization used in elevation charts.

ContourPlot[h[x,y],{x,0,2π},{y,0,2π}]

Note that Mathematica automatically colors the areas between adjacent contours with a color that is approximately proportional to the value of the function in that area.  An alternative method is simply to create a 2D color image, where the color at a particular point is proportional to the value of the function.  Mathematica's DensityPlot provides this functionality.

DensityPlot[h[x,y],{x,0,2π},{y,0,2π}]

Visualizing the behavior of functions in three variable is tougher.  The easiest method for visualizing these functions is to draw the 2D surfaces j[x,y,z]==c corresponding to various contours of the 3D function j[x,y,z].  In Mathematica, the function ContourPlot3D provides this functionality.

j[x_,y_,z_]:=(x^2)+2(y^2)+4(z^2)-1

ContourPlot3D[j[x,y,z],{x,-1,1},{y,-1,1},{z,-1,1}]

Problems

{Cos[φ] (a+b Cos[ψ]),Sin[φ] (a+b Cos[ψ]),b Sin[ψ]}

Visualization of lists

In many applications, our solution will produce a list of numbers instead of a function.  To visualize this discrete set of data, Mathematica supports an analogous set of graphical functions for plotting lists of data.  The Mathematica tutorial Data Visualization summarizes these functions. A good rule of thumb is that if Mathematica has the function Foo that can visualize a continuous function, Mathematica also contains a function ListFoo that visualizes lists of data in a similar way.

Returning to our original function f[x_]=Sin[(1/x)], we shall try to understand its structure by building a table that samples its values on the range [-1,1]. (These values are stored above in the variable flist.)  We can visualize the structure of fList using the Mathematica function ListPlot

ListPlot[fList]

Note that ListPlot has plotted a set of points of the form {i,fList[[i]]}.  In many applications (such as this one), we would like consecutive points joined by a line segment.  The option Joined->True does this.

ListPlot[fList,Joined->True]

Observe that our manually-generated plot is not as nice as the output of Plot for two reasons.   First, the output of Plot has the x-axis correctly varying between -1 and 1. ListPlot varies (incorrectly) between 1 and 201.  The problem is that fList contains no information about the x-coordinate used in generating fList.  We can fix this problem by modifying the definition of fList to contain a list of points of the form {x,f[x]}.

fList=Table[{x,f[x]},{x,-1,1,.01}]

Now, ListPlot will draw each entry of fList as a point resulting in a correct range for the x-axis.

ListPlot[fList,Joined->True]

Second, our visualization using ListPlot looks strange near x==0.  The problem is that Sin[(1/x)] is changing much faster that our Table function is sampling when x approaches 0.  Plot has sophisticated methods for choosing where to sample the variable x based on the behavior of the function f[x].  In particular, Mathematica automatically deduced that something complicated is happening at x==0 and sampled more heavily there. In general, if you are plotting a function of a real variable, always use Plot rather than ListPlot.

Problems

Custom graphics objects

While Mathematica has a wide range of built-in functions for creating visualizations, these functions are useful only for simple visualizations.  In many cases, you may need to create custom visualizations tailored to a specific problem.  To understand the process of creating your own visualization, you will need a deeper understanding of how Mathematica handles graphical objects.

Graphics objects produced by plotting

First, all Mathematica plotting functions produce a Graphics object as output.  (Most of the material here is drawn from the Mathematica tutorial, The Structure of Graphics.)  This object can be assigned to a variable and saved for later manipulation and display using Show.  For example, a and b are two Graphics objects created using Plot,

a=Plot[Sin[x],{x,0,2π}]
b=Plot[Cos[x],{x,0,2π}]

By saving the output of the two previous plots, we can combine these two plots and modify their options using Show,

Show[a,b,PlotRange->{0,1}]

Interestingly, the output of Plot (if viewed in FullForm) is simply a Graphics command with lots of elements corresponding to axes, ticks marks, numbers and, of course, the object being plotted.  For example, the ListPlot below produces the following

FullForm[ListPlot[{{0,0},{1,0}},Joined->True]]

Custom graphics objects

With this insight, we will briefly describe the process of creating our own graphics.  To create your own custom 2D graphics, you simply call the function Graphics with a list of 2D graphics objects.  (In 3D, you must use the function Graphics3D with a list of 3D graphics objects.)  The page Graphics Objects lists of all of various graphics objects available

As a simple example, let's start building up a simple, but interesting 2D graphic. The following Mathematica function creates a filled black rectangle.

Graphics[{Rectangle[{-1,-1},{1,1}]}]

Now, let's change the color to blue by adding the option RGBColor.

Graphics[{
RGBColor[{0,0,1}],
Rectangle[{-1,-1},{1,1}]}]

Next, let's add a green disk in front of the rectangle.

Graphics[{
RGBColor[{0,0,1}],
Rectangle[{-1,-1},{1,1}],
RGBColor[{0,1,0}],
Disk[{0,0}]
}]

Notice that Mathematica drew the blue rectangle first and then the green disk on top of the rectangle.  Both the Rectangle and the Disk are filled 2D shapes.  You can also create 2D curves that represent the boundary of these shapes using the primitives Line and Circle.

Graphics[{
RGBColor[{0,0,1}],
Line[{{1,1},{1,-1},{-1,-1},{-1,1},{1,1}}],
RGBColor[{0,1,0}],
Circle[{0,0}]
}]

You can use a similar approach to make custom 3D graphics.   The tutorial Three-Dimensional Graphics Primitives contains a description of the basic 3D graphics primitives.

Problems

Dynamic visualizations

In the previous two sections, we have focused on creating static visualizations.  While these visualizations provide either 2D or 3D intuition, there remains one more dimension at our disposal to aid in understanding the behavior of a problem or its solution, time. Mathematica supports the creation of interactive visualizations in which users can manipulate a graphical object dynamically.  While Mathematica has lots of support for this activity, the key function for this task is Manipulate. In this section, I will cover the basics of Manipulate.  However, at some point, I suggest that you also review the tutorial Introduction to Manipulate.

Manipulate is a function that takes two inputs:  an expression to be manipulated dynamically and a variable or a set of variables that can be changed dynamically to manipulate the expression.  Here is a simple example,

Manipulate[x!,{x,1,20,1}]

The power of Manipulate becomes more apparent when the expression is a Graphics object.  Here, the variables r, g, b create three sliders that control the color of a rectangle.

Manipulate[Graphics[{
RGBColor[{r,g,b}],
Rectangle[{-1,-1},{1,1}]}],
{r,0,1},
{g,0,1},
{b,0,1}]

Manipulate can also create a discrete set of buttons, when the variable can assume a finite set of choices.  Here, I allow x to be one of three discrete choices for an RGB color using three buttons.

Manipulate[Graphics[{
RGBColor[x],
Rectangle[{-1,-1},{1,1}]}],
{x,{{1,0,0},{0,1,0},{0,0,1}}}]

Below is a more interesting example in which I have attempted to make a blue disk of radius 0.1 revolve (following a unit circle) around a yellow disk of radius 0.2 fixed at the origin.

Manipulate[Graphics[{
RGBColor[{1,1,0}],
Disk[{0,0},0.2],
RGBColor[{0,0,1}],
Disk[{Sin[θ],Cos[θ]},0.1]}],
{θ,0,4π}]

Unfortunately, my Manipulate expression doesn't seem to work too well.  The problem is that Mathematica automatically trims the graphical output to tightly bound both disks.  Since the blue disk is moving, the bounding box is also moving ruining our sense of a blue disk orbiting a fixed yellow disk.  The solution to this problem is specify a fix PlotRange that always contains both disks.

Manipulate[Graphics[{
RGBColor[{1,1,0}],
Disk[{0,0},0.2],
RGBColor[{0,0,1}],
Disk[{Sin[θ],Cos[θ]},0.1]},
PlotRange->1.3],
{θ,0,4π}]

We will build on this example in our next module, where we will use Newton's laws of gravity to solve for the motion of the earth, sun and moon.

Mathematica can also manipulate the position of points that are not constrained to move along a 1-dimensional curve, but are free to move in two dimensions.  When you manipulate a scalar, Mathematica automatically creates a 1-dimensional slider;  when you manipulate a point, Mathematica automatically creates a 2-dimensional slider.  Below is an example of a 2-dimensional slider used to control the size of a blue rectangle by manipulating one of the corners of the rectangle.

Manipulate[Graphics[{RGBColor[{0,0,1}],Rectangle[{0,0},pt]},PlotRange->5,ImageSize->150,Axes->True],{pt,{1,1},{5,5}}]

You can replace 2-dimensional sliders with Locators -- points on the screen -- by specifying that you want a Locator attached to variable point.  You can then tug on the Locator instead of a slider to manipulate the point.

Manipulate[Graphics[{RGBColor[{0,0,1}],Rectangle[{0,0},pt]},PlotRange->5,ImageSize->150,Axes->True],{pt,{1,1},{5,5},Locator}]

Problems