Plotting with Sage

 

The material comes from the book Sage Beginner's Guide by Finch, Craig  Packt Publishing. Kindle Edition. 

plotting symbolic expressions

 

{{{id=2| p1 = plot(sin, (-2*pi, 2*pi), thickness=2.0, rgbcolor=(0.5, 1, 0),legend_label='sin(x)') p2 = plot(cos, (-2*pi, 2*pi), thickness=3.0, color='purple', alpha=0.5,legend_label='cos(x)') plt = p1 + p2 plt.axes_labels(['x', 'f(x)']) show(plt) /// }}}

 

Plotting a parametric function

 

 

 

Plotting a parametric function

 

{{{id=1| var('t') pp = parametric_plot((cos(t), sin(t)), (t, 0, 2*pi),fill=True, fillcolor='blue') pp.show(aspect_ratio=1, figsize=(3, 3), frame=True) /// }}}

 

Making a polar plot
 
 
 
We plotted a polar function, and used several of the plotting features that we've already discussed. There are two subtle points worth mentioning. The function array_factor is a function of two variables, N and theta. In this example, N is more like a parameter, while theta is the independent variable we want to use for plotting. We use the syntax (theta, 0, pi) in the plot function to indicate that theta is the independent variable. The second new aspect of this example is that we used the methods xmin and xmax to set the limits of the x axis for the graphics object called combined_plot. We also used the set_legend_options of the graphics object to adjust the position of the legend to avoid covering up important details of the plot.
 
 

 

Making a polar plot

We plotted a polar function, and used several of the plotting features that we've already discussed. There are two subtle points worth mentioning. The function array_factor is a function of two variables, N and theta. In this example, N is more like a parameter, while theta is the independent variable we want to use for plotting. We use the syntax (theta, 0, pi) in the plot function to indicate that theta is the independent variable. The second new aspect of this example is that we used the methods xmin and xmax to set the limits of the x axis for the graphics object called combined_plot. We also used the set_legend_options of the graphics object to adjust the position of the legend to avoid covering up important details of the plot.

 

{{{id=4| # A linear broadside array of short vertical dipoles # located along the z axis with 1/2 wavelength spacing var('r, theta') N = 7 normalized_element_pattern = sin(theta) array_factor = 1 / N * sin(N * pi / 2 * cos(theta)) /sin(pi / 2 * cos(theta)) array_plot = polar_plot(abs(array_factor), (theta, 0, pi), color='red', legend_label='Array') radiation_plot = polar_plot(abs(normalized_element_pattern* array_factor), (theta, 0, pi), color='blue',legend_label='Radiation') combined_plot = array_plot + radiation_plot combined_plot.xmin(-0.25) combined_plot.xmax(0.25) show(combined_plot, figsize=(2, 5), aspect_ratio=1) /// }}}

 

plotting a vector field

 

Vector fields are used to represent force fields such as electromagnetic fields, and are used to visualize the solutions of differential equations. Sage has a special plotting function to visualize vector fields.

 

{{{id=7| var('x, y') a = plot_vector_field((x, y), (x, -3, 3), (y, -3, 3), color='blue') b = plot_vector_field((y, -x), (x, -3, 3), (y, -3, 3), color='red') show(a + b, aspect_ratio=1, figsize=(4, 4)) /// }}}

 

Plotting data in Sage
 
A) making a scatter plot Scatter plots are used in science and engineering to look for correlation between two variables. A cloud of points that is roughly circular indicates that the two variables are independent, while a more elliptical arrangement indicates that there may be a relationship between them. In the following example, the x and y coordinates are contrived to make a nice plot. In real life, the x and y coordinates would typically be read in from data files. Enter the following code:

Plotting data in Sage

 

A) making a scatter plot Scatter plots are used in science and engineering to look for correlation between two variables. A cloud of points that is roughly circular indicates that the two variables are independent, while a more elliptical arrangement indicates that there may be a relationship between them. In the following example, the x and y coordinates are contrived to make a nice plot. In real life, the x and y coordinates would typically be read in from data files. Enter the following code:

 

{{{id=9| def noisy_line(m, b, x): return m * x + b + 1/2 *(random() - 1/2) slope = 1.0 intercept = -0.5 x_coords = [random() for t in range(50)] y_coords = [noisy_line(slope, intercept, x) for x in x_coords] sp = scatter_plot(zip(x_coords, y_coords)) sp += line([(0.0, intercept), (1.0, slope+intercept)], color='red') sp.show() /// }}}

 

What just happened? We created a list of randomized x coordinates using the built-in random function. This function returns a random number in the range 0 ≤ x < 1. We defined a function called noisy_line that we then used to create a list of randomized y coordinates with a linear relationship to the x coordinates. We now have a list of x coordinates and a list of y coordinates, but the scatter_plot function needs a list of (x,y) tuples. The zip function takes the two lists and combines them into a single list of tuples. The scatter_plot function returns a graphics object called sp. To add a line object to the plot, we use the following syntax:
 
sp += line([(x1, y1), (x2,y2)], color='red') The += operator is a way to increment a variable; x+=1 is a shortcut for x = x + 1. Because the + operator also combines graphics objects, this syntax can be used to add a graphics object to an existing graphics object.

 

Explanations for the previews graph: We created a list of randomized x coordinates using the built-in random function. This function returns a random number in the range 0 ≤ x < 1. We defined a function called noisy_line that we then used to create a list of randomized y coordinates with a linear relationship to the x coordinates. We now have a list of x coordinates and a list of y coordinates, but the scatter_plot function needs a list of (x,y) tuples. The zip function takes the two lists and combines them into a single list of tuples. The scatter_plot function returns a graphics object called sp. To add a line object to the plot, we use the following syntax:

sp += line([(x1, y1), (x2,y2)], color='red') The += operator is a way to increment a variable; x+=1 is a shortcut for x = x + 1. Because the + operator also combines graphics objects, this syntax can be used to add a graphics object to an existing graphics object.

 

 

Plotting a list

Sometimes, you need to plot a list of discrete data points. The following example might be found in an introductory digital signal processing (DSP) course. We will use lists to represent digital signals. We sample the analogue function cosine(t) at two different sampling rates, and plot the resulting digital signals.

{{{id=12| # Use list_plot to visualize digital signals # Undersampling and oversampling a cosine signal sample_times_1 = srange(0, 6*pi, 4*pi/5) sample_times_2 = srange(0, 6*pi, pi/3) data1 = [cos(t) for t in sample_times_1] data2 = [cos(t) for t in sample_times_2] plot1 = list_plot(zip(sample_times_1, data1), color='blue') plot1.axes_range(0, 18, -1, 1) plot1 += text("Undersampled", (9, 1.1), color='blue', fontsize=12) plot2 = list_plot(zip(sample_times_2, data2), color='red') plot2.axes_range(0, 18, -1, 1) plot2 += text("Oversampled", (9, 1.1), color='red', fontsize=12) g = graphics_array([plot1, plot2], 2, 1) # 2 rows, 1 column g.show(gridlines=["minor", False]) /// }}}

Explanations: The function list_plot works a lot like scatter_plot from the previous example, so I won't explain it again. We used the method axes_range(x_min, x_max, y_min, y_max) to set the limits of the x and y axes all at once. Once again, we used the += operator to add a graphics object to an existing object. This time, we added a text annotation instead of a line. The basic syntax for adding text at a given (x,y) position is  text('a string', (x,y)). To see the options that text accepts, type the following: sage: text.options {'vertical_alignment': 'center', 'fontsize': 10, 'rgbcolor': (0, 0, 1), 'horizontal_alignment': 'center', 'axis_coords': False} To display the two plots, we introduced a new function called graphics_array, which uses the basic syntax: graphics_array([plot_1, plot_2, ..., plot_n], num_rows, num_columns) This function returns another graphics object, and we used the show method to display the plots. We used the keyword argument gridlines=["minor", False] to tell Sage to display vertical lines at each of the minor ticks on the x axis. The first item in the list specifies vertical grid lines, and the second specifies horizontal grid lines. The following options can be used for either element: "major" Grid lines at major ticks "minor" Grid lines at major and minor ticks False No grid lines

 

Plotting  data with matplotlib
 
 
 
Because matplotlib plots arrays of points, it is well suited to working with data. You can make many kinds of charts and publication-quality graphics with matplotlib.
 
Finch, Craig (2011-05-11). Sage Beginner's Guide (p. 161). Packt Publishing. Kindle Edition. 
 
Because matplotlib plots arrays of points, it is well suited to working with data. You can make many kinds of charts and publication-quality graphics with matplotlib.
 
 

 

Plotting  data with matplotlib

Because matplotlib plots arrays of points, it is well suited to working with data. You can make many kinds of charts and publication-quality graphics with matplotlib.

 

{{{id=11| import matplotlib.pyplot as plt radius = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0] area = [3.14159, 12.56636, 28.27431, 50.26544, 78.53975, 113.09724] square = [1.0, 4.0, 9.0, 16.0, 25.0, 36.0] plt.plot(radius, area, label='Circle') plt.plot(radius, square, marker='o', linestyle='--', color='r', label='Square') plt.xlabel('Radius/Side') plt.ylabel('Area') plt.title('Area of Shapes') plt.legend() plt.savefig('demo1.png') plt.close() /// }}} {{{id=17| import numpy import matplotlib.pyplot as plt x = numpy.arange(-2 * numpy.pi, 2 * numpy.pi, 0.1) func1 = numpy.sin(x) func2 = numpy.cos(x) plt.figure(figsize=(5.5, 3.7)) # size in inches plt.plot(x, func1, linewidth=2.0, color=(0.5, 1,0), label='$f(x)=sin(x)$') plt.plot(x, func2, linewidth=3.0, color='purple', alpha=0.5, label='$f(x)=cos(x)$') plt.xlabel('$x$') plt.ylabel('$f(x)$') plt.title('Plotting with matplotlib') plt.legend(loc='lower left') plt.savefig('demo1.png') plt.close() /// }}}

 

What just happened? We gained access to matplotlib functions and types with the following line: import matplotlib.pyplot as plt We can now access these functions as plt.function_name. We also import numpy so that we can use its numerical arrays.
 
 
 
There is an important difference between the Sage plot function and the matplotlib plot function. matplotlib always plots lists or arrays of discrete points, rather than callable symbolic expressions. This block of code creates an array of x values: x = numpy.arange(-2*numpy.pi, 2*numpy.pi, 0.1) func1 = numpy.sin(x) func2 = numpy.cos(x) func1 and func2 are arrays of y values.
 
Notice that we specify the NumPy version of sin and cos, since the Sage functions don't know what to do with NumPy arrays.
 
The syntax for plotting with matplotlib is as follows:
 
plt.figure() plt.plot(x_values, y_values) The first line creates an empty figure. The optional argument figsize=(x_size, y_size) sets the figure size in inches.
 
The second line plots the data points that are specified in the arrays or lists. By default, the points are connected with straight line segments. If you specify points that are too far apart, you will see the line segments instead of a smooth curve. The options for the plt.plot function are very similar to the options for the Sage plot function.
 
The following code labels the x and y axes, and places a title above the figure:
 
plt.xlabel('x') plt.ylabel('f(x)')
 
plt.title('Plotting with matplotlib') plt.legend(loc='lower right')
 
The legend method places a legend on the figure. You can use TeX to format any text on the plot by wrapping the text in dollar signs.
 
The following code actually displays the plot:
 
plt.savefig('demo1.png') plt.close()
 
If you are running this example from the notebook interface, the graphic will automatically appear in the notebook. If you're running it in the interactive shell, you won't see any output. The savefig function will save an image file in your home directory. To specify a different path for saving files, pass a full or relative path in addition to the file name.
 
 
 
matplotlib can save figures in a variety of image formats, such as png, pdf, ps (PostScript), eps (encapsulated PostScript), and svg (scalable vector graphics). It will automatically determine the correct format from the extension of the file name. You can also use the format keyword to specify the image format. PNG is a raster format, which is compatible with Microsoft Office and OpenOffice. For publications, it is best to use a vector format like PostScript, EPS, or PDF. The SVG format is used for displaying vector graphics on the Web.

 

What just happened? We gained access to matplotlib functions and types with the following line: import matplotlib.pyplot as plt We can now access these functions as plt.function_name. We also import numpy so that we can use its numerical arrays.

here is an important difference between the Sage plot function and the matplotlib plot function. matplotlib always plots lists or arrays of discrete points, rather than callable symbolic expressions. This block of code creates an array of x values: x = numpy.arange(-2*numpy.pi, 2*numpy.pi, 0.1) func1 = numpy.sin(x) func2 = numpy.cos(x) func1 and func2 are arrays of y values.

Notice that we specify the NumPy version of sin and cos, since the Sage functions don't know what to do with NumPy arrays.

The syntax for plotting with matplotlib is as follows:

plt.figure() plt.plot(x_values, y_values) The first line creates an empty figure. The optional argument figsize=(x_size, y_size) sets the figure size in inches.

The second line plots the data points that are specified in the arrays or lists. By default, the points are connected with straight line segments. If you specify points that are too far apart, you will see the line segments instead of a smooth curve. The options for the plt.plot function are very similar to the options for the Sage plot function.

 

The following code labels the x and y axes, and places a title above the figure:

 

plt.xlabel('x') plt.ylabel('f(x)')

 

plt.title('Plotting with matplotlib') plt.legend(loc='lower right')

 

The legend method places a legend on the figure. You can use TeX to format any text on the plot by wrapping the text in dollar signs.

 

The following code actually displays the plot:

 

plt.savefig('demo1.png') plt.close()

 

If you are running this example from the notebook interface, the graphic will automatically appear in the notebook. If you're running it in the interactive shell, you won't see any output. The savefig function will save an image file in your home directory. To specify a different path for saving files, pass a full or relative path in addition to the file name.

matplotlib can save figures in a variety of image formats, such as png, pdf, ps (PostScript), eps (encapsulated PostScript), and svg (scalable vector graphics). It will automatically determine the correct format from the extension of the file name. You can also use the format keyword to specify the image format. PNG is a raster format, which is compatible with Microsoft Office and OpenOffice. For publications, it is best to use a vector format like PostScript, EPS, or PDF. The SVG format is used for displaying vector graphics on the Web.

 

 

 

Making a bar chart Bar charts are often used to present experimental data in scientific papers. Let's make a chart with bars that represent the average value of some experimental data and add error bars to represent the standard deviation:
 
 

Making a bar chart Bar charts are often used to present experimental data in scientific papers. Let's make a chart with bars that represent the average value of some experimental data and add error bars to represent the standard deviation:

 

 

 

{{{id=20| import numpy import matplotlib.pyplot as plt # Define experimental data cluster1_data = numpy.array([9.7, 3.2]) cluster1_x = numpy.array([2,4]) cluster1_error = numpy.array([1.3, 0.52]) cluster2_data = numpy.array([6.8, 7.3]) cluster2_x = numpy.array([8,10]) cluster2_error = numpy.array([0.72, 0.97]) # Join data arrays for plotting data = numpy.concatenate([cluster1_data, cluster2_data]) bar_centers = numpy.concatenate([cluster1_x, cluster2_x]) errors = numpy.concatenate([cluster1_error, cluster2_error]) # Plot fig = plt.figure(figsize=(5,4)) # size in inches plt.bar(bar_centers, data, yerr=errors, width=2.0, align='center', color='white', ecolor='black') plt.ylabel('outcome') plt.text(4, 4, '*', fontsize=14) # Label ticks on x axis axes = fig.gca() axes.set_xticks(bar_centers) axes.set_xticklabels(['trial 1', 'trial 2', 'trial 3', 'trial 4']) plt.savefig('Bar_Chart.png') plt.close() /// }}}

 

Making a pie chart

Making a pie chart

 

 

{{{id=18| import numpy import matplotlib.pyplot as plt data = [1.0, 10.0, 20.0, 30.0, 40.0] explode = numpy.zeros(len(data)) explode[3] = 0.1 plt.figure(figsize=(4, 4)) plt.pie(data, explode=explode, labels=['a', 'b', 'c', 'd', 'e']) plt.title('Revenue sources') plt.savefig('Pie_chart.png') plt.close() /// }}}

 NOTE: We made a pie chart. The pie function in matplotlib only requires one argument, which is a list of numbers that indicate the relative size of the slices. The explode option takes a list of numbers that show how far to offset each piece of the pie from the centre. In this case, we created an array of zeros and set the fourth element to 0.1, which offset the fourth slice of the pie. We used the keyword explode to pass this array to the pie function. We used the labels keyword to pass a list of strings to be used as labels for each slice.

Plotting a Histogram

matplotlib has a built-in function for making histograms, which are used to visualize the distribution of values in a set of data. In this example, we will generate an array of random numbers that are drawn from a Gaussian distribution:

{{{id=23| import numpy import matplotlib.pyplot as plt data = numpy.random.normal(0, 1, size=1000) plt.figure(figsize=(4, 4)) plt.hist(data, normed=True, facecolor=(0.9, 0.9, 0.9)) plt.savefig('Histogram.png') plt.close() /// }}}

What just happened? We used the hist function to visualize the distribution of values in an array of pseudo-random numbers. hist requires one argument, which is an array containing the data. In practice, the data would typically consist of experimental measurements, sensor data, or the results of a Monte Carlo simulation. We used the optional argument normed=True to indicate that the histogram should be normalized, which means that its integral is one. The facecolor keyword was used to specify the fill color of the bars as a tuple of R, G, B values.

 

Plotting in three dimensions Sage can make 3D plots for visualizing functions of two variables, as well as parametric plots that create three-dimensional surfaces. It also has a variety of tools for making two-dimensional representations of three-dimensional surfaces.
Make an interactive 3D plot

Plotting in three dimensions

Sage can make 3D plots for visualizing functions of two variables, as well as parametric plots that create three-dimensional surfaces. It also has a variety of tools for making two-dimensional representations of three-dimensional surfaces.

 

Make an interactive 3D plot

 

 

{{{id=26| var('x, y') p3d = plot3d(y^2 + 1 - x^3 - x, (x, -pi, pi), (y, -pi, pi)) p3d.show() /// }}}

 

If you run this example in the notebook interface, a Java applet called Jmol will run in the cell below the code. If you run it from the interactive shell, Jmol will launch as a stand-alone application. Clicking and dragging on the figure with the left mouse button will rotate the plot in 3D space. Clicking and dragging with the centre button, or moving the scroll wheel, zooms in and out. Right-clicking brings up a menu that allows you to set various options for Jmol. Since Jmol is also used to visualize the 3D structures of molecules, some of the options are not relevant for plotting functions. Here is a screenshot of the function, plotted with Jmol:
 
What just happened? We made a cool 3D plot that allowed us to explore a function of two variables. When running Jmol as an applet in a worksheet, you can click on the "Get Image" link below the plot to save an image of the plot in its current state. However, the image quality is not particularly high because it is saved in JPEG format. When Jmol is called from the command line, it runs as a stand-alone application, and more options are available. You can save files in JPEG, GIF, PPM, PNG, or PDF format. Note that the PDF format is a bitmap embedded in a PDF file, rather than a true vector representation of the surface. The syntax forusing plot3d is very simple: plot3d(f(x,y), (x, x_min, x_max), (y, y_min, y_max)) There are a few optional arguments to the show method that you can use to alter the appearance of the plot. Setting mesh=True plots a mesh on the surface, and setting dots=True plots a small sphere at each point. You can also use the transformation keyword argument to apply a transformation to the data—see the plot3d documentation for more information. Higher quality output We can improve the quality of saved images using ray tracing, which is an algorithm for generating images that is based on optical principles. Sage comes with ray tracing software called Tachyon, which can be used to view 3D plots. To activate Tachyon, use the show method with the viewer keyword as shown below: p3d.show(viewer='tachyon', frame=False, axes=True) Depending on the speed of your computer, the ray tracing may require a few seconds to a few minutes.

 

If you run this example in the notebook interface, a Java applet called Jmol will run in the cell below the code. If you run it from the interactive shell, Jmol will launch as a stand-alone application. Clicking and dragging on the figure with the left mouse button will rotate the plot in 3D space. Clicking and dragging with the centre button, or moving the scroll wheel, zooms in and out. Right-clicking brings up a menu that allows you to set various options for Jmol. Since Jmol is also used to visualize the 3D structures of molecules, some of the options are not relevant for plotting functions. Here is a screenshot of the function, plotted with Jmol:

What just happened? We made a cool 3D plot that allowed us to explore a function of two variables. When running Jmol as an applet in a worksheet, you can click on the "Get Image" link below the plot to save an image of the plot in its current state. However, the image quality is not particularly high because it is saved in JPEG format. When Jmol is called from the command line, it runs as a stand-alone application, and more options are available. You can save files in JPEG, GIF, PPM, PNG, or PDF format. Note that the PDF format is a bitmap embedded in a PDF file, rather than a true vector representation of the surface. The syntax forusing plot3d is very simple: plot3d(f(x,y), (x, x_min, x_max), (y, y_min, y_max)) There are a few optional arguments to the show method that you can use to alter the appearance of the plot. Setting mesh=True plots a mesh on the surface, and setting dots=True plots a small sphere at each point. You can also use the transformation keyword argument to apply a transformation to the data—see the plot3d documentation for more information. Higher quality output We can improve the quality of saved images using ray tracing, which is an algorithm for generating images that is based on optical principles. Sage comes with ray tracing software called Tachyon, which can be used to view 3D plots. To activate Tachyon, use the show method with the viewer keyword as shown below: p3d.show(viewer='tachyon', frame=False, axes=True) Depending on the speed of your computer, the ray tracing may require a few seconds to a few minutes.

 

 

 

Parametric 3D plotting Sage can also plot functions of two variables that are defined in terms of a parameter. You can make very complex surfaces in this way.
 

 

Parametric 3D plotting

Sage can also plot functions of two variables that are defined in terms of a parameter. You can make very complex surfaces in this way.

 

{{{id=29| var('u, v') f1 = (4 + (3 + cos(v)) * sin(u), 4 + (3 + cos(v)) * cos(u), 4 + sin(v)) f2 = (8 + (3 + cos(v)) * cos(u), 3 + sin(v), 4 + (3 + cos(v))* sin(u)) p1 = parametric_plot3d(f1, (u, 0, 2 * pi), (v, 0, 2 * pi),texture="red") p2 = parametric_plot3d(f2, (u, 0, 2 * pi), (v, 0, 2 * pi),texture="blue") combination = p1 + p2 combination.show() /// }}}

 

What just happened? We made a very complex 3D shape using the parametric_plot3d function. The optional arguments for this function are the same as the options for the plot3d function.
 

What just happened? We made a very complex 3D shape using the parametric_plot3d function. The optional arguments for this function are the same as the options for the plot3d function.

 

 

 

Contour plots

Sage can also make contour plots, which are 2-D representations of 3-D surfaces. While 3D plots are eye-catching, a 2D plot can be a more practical way to convey information about the function or data set.

{{{id=32| var('x, y') text_coords = (2, -3.5) cp = contour_plot(y^2 + 1 - x^3 - x, (x, -3, 3), (y, -3, 3),contours=8, linewidths=srange(0.5, 4.0, 0.5),fill=False,labels=True, label_colors='black', cmap='gray', colorbar=False) cp += text("Contour", text_coords) ip = implicit_plot(y^2 + 1 - x^3 - x, (x, -3, 3), (y, -3, 3)) ip += text("Implicit", text_coords) rp = region_plot(y^2 + 1 - x^3 - x < 0, (x, -3, 3), (y, -3, 3), incol=(0.8, 0.8, 0.8)) # color is an (R,G,B) tuple rp += text("Region", text_coords) dp = density_plot(y^2 + 1 - x^3 - x, (x, -3, 3), (y, -3, 3)) dp += text("Density", text_coords) show(cp) show(ip) show(rp) show(dp) /// }}} {{{id=35| /// }}}