Using matplotlib

126 days ago by jharriga

General

Matplotlib is a data plotting library for python, and is included in Sage. It was designed to be an opensource alternative to Matlab's plotting functions, and it is generally viewed to be as good as or better than Matlab for 2D plotting. There is a learning curve for efficiently using matplotlib. This guide is designed to help you understand it's structure, how it works with Sage, and provide reference code snippets. A good overview is here:

Class structure

To effectively do things and customize plots, an understanding of the class structure is necessary. The most important thing to know is that there are two objects you'll be working with the most: figures, and axes. A figure is a container for an axes, and an axes contains plotting methods and primative objects such as tick marks. So generally your code will look like this:

  1. Make (or clear) a figure (either implicitly or explicitly)
  2. Make an axes (either implicitly or explicitly)
  3. Plot in the axes
  4. Customize the axes (title, axis labels, ticks, etc)
  5. Save the figure

There are other good things to know, read these for details:

There is another important thing to know about classes, and that is how to browse classes from within Sage. To do this, you put a dot after the main class object, then press tab. This brings up a list of all elements the object has in it. After you see a list of elements, you can click one of them and it will be inserted in your code. After that, you put a question mark after the line of code, and execute it to get the help documentation on it.

How Sage displays images: show() vs savefig('fig')

Before continuing on, we need to understand how Sage displays images in the notebook. It's pretty simple. Each cell has it's own current directory. If, after executing that cell, there is an image in that directory, it is displayed as a result.

What this means is that instead of using the show() function, as many online examples for matplotlib use, we must use the savefig() function. The examples below will show the usage.

Coding style

There are two supported coding styles when using matplotlib. One is an explicit style, and one is a less verbose implicit style. The implicit style requires less code and uses a state machine with current figures and axes.

Implicit style - using the pyplot state machine

With the implicit style, the figure and axes are created automatically. When properties are changed, they apply to the current figure and current axes. We'll generally use the implicit style unless we're doing something advanced.

import matplotlib.pyplot as plt #import matplotlib import numpy as np #import numpy to use some functions x = np.arange(0, 10, 0.2) #create x vector y = np.sin(x) #create y vector plt.plot(x, y) #create figure, create axes, and plot in the axes plt.savefig('fig') #save figure 
       

There's something important to note when using this method. The first time this code is run, the pyplot state machine will create a new figure and new axes because there is nothing to plot to. However, subsequent calls to the plot function will plot to the current figure and current axes. So what will happen is your plots will overlay on each other. Try running the above code several times. The line color changes because you're adding multiple plots to the same axes.

There are two ways to get around this. One is to use the "hold=false" option in the plot function. The second, which I prefer, is to clear the current figure before plotting with clf. Examples are below.

#avoid overlaying plots by turning hold off plt.plot(x, y, hold=false) plt.savefig('fig') 
       
#avoid overlaying plots by clearing the current figure plt.clf() plt.plot(x, y) plt.savefig('fig') 
       

Explicit style - creating figures and axes

With the explicit style, code is longer but more explicit.

import matplotlib.pyplot as plt import numpy as np x = np.arange(0, 10, 0.2) y = np.sin(x) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(x, y) fig.savefig('fig') 
       

Customizing a plot

Most customizations are done within the axes object. Some examples are below. When changing a figure size, it's useful to know the get current figure command, which is gcf.

Below is some implicit styled code which has been customized in various ways. To make a less elaborate plot, just delete out parts you don't need.

import matplotlib.pyplot as plt import numpy as np x = np.arange(0, 10, 0.2) r = np.random.randn(100) plt.clf() #clear current figure #code for first subplot plt.subplot(121) plt.plot(x,np.cos(x),'ro') plt.plot(x,np.sin(x),'g.-') #plots overlay if hold is off plt.title('Voltage vs time') plt.xlabel('time [ms]') plt.ylabel('voltage [volts]') plt.legend(('V$_{in}$','V$_{out}$')) #switch to second subplot plt.subplot(122) bins=np.arange(-3,3,.25) #it's always a *great* idea to plt.hist(r,bins=bins) #specify your own bins on histograms plt.title('Histogram of jitter') plt.xlabel('phase [degrees]') #format and save the figure plt.gcf().set_size_inches(10,4) plt.gcf().suptitle('Analysis of communications PHY') plt.gcf().subplots_adjust(top=.85) plt.savefig('fig') 
       

Hundreds of examples, with source code

Above is just a small sampling of the plots that can be created. The link below is a gallery with all kinds of different plots - pretty much anything you could think of. Clicking on one of them opens a page which has a link to the source code. You should be able to run the code here, the only thing you need to change is to replace show() with savefig('fig') in the last line to display the image.