Friday, January 10, 2020

An advanced Graphical Output in matplotlib

Here, we introduce a more advanced syntax that harnesses the full power of matplotlib. It gives the user more options and greater control.

An efficient way to learn this new syntax is simply to look at an example in the figure shown below,



It shows multiple plots laid out in the same window, which is produced by the following code:

import numpy as np
import matplotlib.pyplot as plt


# Define the sinc function, with output for x=0
# defined as a special case to avoid division by zero
def s(x):
    a = np.where(x == 0., 1., np.sin(x) / x)
    return a


x = np.arange(0., 10., 0.1)
y = np.exp(x)

t = np.linspace(-15., 15., 150)
z = s(t)

# create a figure window
fig = plt.figure(figsize=(9, 7))

# subplot: linear plot of exponential
ax1 = fig.add_subplot(2, 2, 1)
ax1.plot(x, y, 'C0')
ax1.set_xlabel('time (ms)')
ax1.set_ylabel('distance (mm)')
ax1.set_title('exponential')

# subplot: semi-log plot of exponential
ax2 = fig.add_subplot(2, 2, 2)
ax2.plot(x, y, 'C2')
ax2.set_yscale('log')
# ax2.semilogy(x, y, 'C2')  # same as 2 previous lines
ax2.set_xlabel('time (ms)')
ax2.set_ylabel('distance (mm)')
ax2.set_title('exponential')

# subplot: wide subplot of sinc function
ax3 = fig.add_subplot(2, 1, 2)
ax3.plot(t, z, 'C3')
ax3.axhline(color='gray')
ax3.axvline(color='gray')
ax3.set_xlabel('angle (deg)')
ax3.set_ylabel('electric field')
ax3.set_title('sinc function')

# fig.tight_layout() adjusts white space to
# avoid collisions between subplots
fig.tight_layout()
fig.savefig("figures/multiplePlots1window.pdf")
plt.show()


After defining several arrays for plotting, the above program opens a figure window in line 19 with the statement

fig = plt.figure(figsize=(9, 7))

The matplotlib statement above creates a Figure object, assigns it the name fig, and opens a blank figure window. Thus, just as we give lists, arrays, and numbers variable names (e.g., a = [1, 2, 5, 7],
dd = np.array([2.3, 5.1, 3.9]), or st = 4.3), we can give a figure object and the window it creates a name: here it is fig. In fact we can use the figure function to open up multiple figure objects with
different figure windows. The statements

fig1 = plt.figure()
fig2 = plt.figure()

open up two separate windows, one named fig1 and the other fig2. We can then use the names fig1 and fig2 to plot things in either window. The figure function need not take any arguments if you are satisfied with the default settings such as the figure size and the background color. On the other hand, by supplying one or more keyword arguments, you can customize the figure size, the background color, and a few other properties. For example, in the program listing (line 25), the keyword argument figsize sets the width and height of the figure window. The default size is (8, 6); in our program we set it to (9, 8), which is a bit wider and higher than the default size. In the example above, we also choose to open only a single window, hence the single figure call.

The fig.add_subplot(2, 2, 1) in line 22 is a matplotlib function that divides the figure window into 2 rows (the first argument) and 2 columns (the second argument). The third argument creates a subplot
in the first of the 4 subregions (i.e., of the 2 rows 2 columns) created by the fig.add_subplot(2, 2, 1) call.

The ax1.plot(x, y, 'C0') in line 23 directs Python to plot the previously defined x and y arrays onto the axes named ax1. The statement ax2 = fig.add_subplot(2, 2, 2) draws axes in the second, or upper right, quadrant of the figure window. The statement ax3 = fig.add_subplot(2, 1, 2) divides the figure window into 2 rows (first argument) and 1 column (second argument), creates axes in the second or these two sections, and assigns those axes (i.e., that subplot) the name ax3. That is, it divides the figure window into 2 halves, top and bottom, and then draws axes in the half number 2 (the third argument), or lower half of the figure window.

You may have noticed in the above code that some of the function calls are a bit different from those used before, so:
xlabel('time (ms)') ! set_xlabel('time (ms)')
title('exponential') ! set_title('exponential')
etc.

The call ax2.set_yscale('log') sets the y-axes in the second plot to be logarithmic, thus creating a semi-log plot. Alternatively, this can be done with a ax2.semilogy(x, y, 'C2') call. Using the prefixes ax1, ax2, or ax3, directs graphical instructions to their respective subplots. By creating and specifying names for the different figure windows and subplots within them, you access the different plot windows more efficiently.


Share:

0 comments:

Post a Comment