Python:Starting Plots

From PrattWiki
Revision as of 01:28, 16 December 2019 by DukeEgr93 (talk | contribs) (Object Oriented)
Jump to navigation Jump to search

This sandbox is to create a new version of the plotting reference. The first goal is to keep it simple. The second goal is to satisfy the first goal.

Preamble

The explanations and programs below all assume that you have already run the code:

import numpy as np
import matplotlib.pyplot as plt

Starting a Plot

In Python, there are several different ways to start and create a plot. The process you choose will generally depend on how complicated the plot will be. Will it be a simple or will it have labels and titles and other items? Will it have subplots? Will it have one or more 3-D components?

Very Simple

If you just want to make a quick plot and aren't planning on doing much else with it, you can use the plt module itself to do all the work. The Usage Guide at matplotlib refers to this as the state-machine environment. For example:

t = np.linspace(0, 10, 1000)
y = np.cos(t)
plt.figure()
plt.plot(t, y)

will create a new figure window and plot the data set using a solid blue line. The plt module does have some basic control over things like labels and titles, but if you are planning to add labels and titles you should see the next section. Basically, using plt to do all the work is fine if you want to just look at a data set; anything more formal than that should what matplotlib calls the pyplot style.

Object Oriented

If you are going to create a figure that has one or more sets of subplots, or where one or more of the subplots have graphs that need labels and titles and such, you should use a more formal method of creating your plot. There are two different ways to create the infrastructure for your figure window:

  • If you have one or more subplots, and the subplots are arranged in a rectangular grid, and the subplots are all 2-D plots, and you are using most or all of the subplots, you can create the figure and each set of axes at the same time. If you have more than one subplot, you will first specify the number of rows of subplots and then the number of columns of subplots. You should also specify a figure number - this will re-use a figure window if it is open rather than creating a new window every time you run the program. Finally, you should clear the figure window to get rid of any previous subplots. Here are some examples:
    • If you want to create a figure (call it figure 1) that has a single set of axes in it, you could run:
fig, ax = plt.subplots(num=1, clear=True)
In this case, fig will have access to figure-level commands and ax will have access to axes-level commands. You could then make a plot in the one set of axes with:
t = np.linspace(0, 10, 1000)
y = np.cos(t)
ax.plot(t, y)
  • If you want to create a figure (call it figure 2) that has six subplots arranged in two rows of three columns each, you could run:
fig, ax = plt.subplots(2, 3, num=1, clear=True)
In this case, fig will still have access to figure-level commands; ax, however, is now a 2x3 array of axes objects. If you want to plot something in one of the subplots, you will need to specify which of the axes objects to use by slicing ax. For example, if you were to want to put a plot in the top (row 0) right (column 2) set of axes, you could use the following code:
t = np.linspace(0, 10, 1000)
y = np.cos(t)
ax[0][2].plot(t, y)
  • If you have one or more subplots, but the subplots are not arranged in a rectangular grid, or at least one of the subplots is not a 2-D plot, or you are not using most or all of the subplots, you can create the figure handle with plt.figure() and then create the axes handles separately with individual calls to fig.add_subplot(). The plt.figure() command should still have arguments indicating which figure to activate and to clear it. The fig.add_subplot() command needs information about which plot to add. The first two arguments define the hypothetical number of rows and columns of subplots you would have if you were adding all the subplots in such a grid. The third argument indicates which one of those subplots you actually want to add. Here are some examples of that:
  • If you want to create a figure that only activates the top right subplot used above and leaves the rest of the space blank, you could do that with:
fig = plt.figure(num=1, clear=True)
ax = fig.add_subplot(2, 3, 3)
This breaks the figure into two rows of three columns but only creates a handle to the subplot that is third (starting with 1 at top left, counting up as you go right, and then wrapping to the next row)
  • If you want to create a figure that activates the top right and bottom middle subplots of a 2x3 grid and leaves the rest of the space blank, you could do that with:
fig = plt.figure(num=1, clear=True)
ax1 = fig.add_subplot(2, 3, 3)
ax2 = fig.add_subplot(2, 3, 5)
  • If you want to create a figure that is broken up into three parts - a tall graph that takes up the entire left side of the figure and two smaller graphs that are stacked on top of each other on the right, note that the tall graph is the first of two subplots that would be created if you broke the figure into one row of two columns. On the other hand, the two smaller graphs would be the second and fourth ones that would be created if you broke the figure into two rows of two columns of plots:
fig = plt.figure(num=1, clear=True)
ax_left = fig.add_subplot(1, 2, 1)
ax_right_top = fig.add_subplot(2, 2, 2)
ax_right_bot = fig.add_subplot(2, 2, 4)
  • Note: with matplotlib, if you create a subplot that interferes with / covers up part of another subplot, matplotlib will draw it on top of the subplots created earlier. This method is therefore very flexible but potentially dangerous.

Finishing Up and Saving

After you have done everything you want to the figure and all the subplots, you will almost always want to issue the command:

fig.tight_layout()

As long as no two subplots are supposed to occupy the same space, this command will go through and make sure that no two subplots interfere with each other but will also optimize the use of space for all the subplots collectively. This command should run just before saving anything because you need to make sure that you have made all changes that might impact how much space a subplot will take up before optimizing the spaces. Changes made after the command is run will not trigger a re-optimization.

Finally, you can save the figure. The command for this is

fig.savefig('FILE.EXT')

where the extension EXT will tell Python what kind of file to make. Common extensions include eps, ps, png, jp(e)g, svg, and pdf.