Monday, January 6, 2020

Setting plotting limits

We often want to restrict the range of numerical values over which we plot data or functions. In these cases we may need to manually specify the plotting window or, alternatively, we may wish to exclude data points that are outside some set of limits. Let's see methods for doing this.

Setting plotting limits

Suppose you want to plot the tangent function over the interval from 0 to 10. The following script offers an straightforward first attempt:

import numpy as np
import matplotlib.pyplot as plt

theta = np.arange(0.01, 10., 0.04)
ytan = np.tan(theta)

plt.figure(figsize=(8.5, 4.2))
plt.plot(theta, ytan)
plt.savefig('figures/tanPlot0.pdf')
plt.show()

The resulting plot is shown below:


doesn’t quite look like what you might have expected for tan teta  vs. theta . The problem is that tan theta diverges at theta =pi/2;3pi/2;5pi/2,... which leads to large spikes in the plots as values in the theta array come near those values. Of course, we don’t want the plot to extend all the way out to 1 in the y direction, nor can it. Instead, we would like the plot to extend far enough that we get the idea of what is going on as y ->+infinity, -infinity, but we would still like to see the behavior of the graph near y = 0. We can restrict the range of ytan values that are plotted using the matplotlib function ylim, as shown in the script below:

import numpy as np
import matplotlib.pyplot as plt

theta = np.arange(0.01, 10., 0.04)
ytan = np.tan(theta)

plt.figure(figsize=(8.5, 4.2))
plt.plot(theta, ytan)
plt.ylim(-8, 8)  # restricts range of y axis from -8 to +8
plt.axhline(color="gray", zorder=-1)
plt.savefig('figures/tanPlot1.pdf')
plt.show()

Figure below shows the plot produced by this script, which now looks much more like the familiar tan function we know.


We have also included a call to the axline function to create an x axis. Recall that for theta =pi/2, tan theta- -> +infinity and tan theta+ -> -infinity; in fact, tan theta diverges to +- infinity at every odd half integral value of theta. Therefore, the vertical blue lines at theta =pi/2; 3pi/2 ; 5pi/2 should not appear in a proper plot of tan theta  vs.theta . However, they do appear because the plot function simply draws lines between the data points in the x-y arrays provided the plot function’s arguments. Thus, plot draws a line between the very large positive and negative ytan values corresponding to the theta values on either side of pi/2 where tan  diverges to +- infinity. It would be nice to exclude that line.

We can exclude the data points near  theta =pi/2; 3pi/2 and 5pi/2 in the above plot, and thus avoid drawing the nearly vertical lines at those points, using NumPy’s masked array feature. The code below shows how this is done:

import numpy as np
import matplotlib.pyplot as plt

theta = np.arange(0.01, 10., 0.04)
ytan = np.tan(theta)
ytanM = np.ma.masked_where(np.abs(ytan) > 20., ytan)

plt.figure(figsize=(8.5, 4.2))
plt.plot(theta, ytanM)
plt.ylim(-8, 8)  # restricts y-axis range from -8 to +8
plt.axhline(color="gray", zorder=-1)
plt.savefig('figures/tanPlotMasked.pdf')
plt.show()

The masked array feature is implemented in line 6 with a call to NumPy’s masked_where function in the sub-module ma (masked array). It is called by writing np.ma.masked_where. The masked_where function works as follows. The first argument sets the condition for masking elements of the array; the array is specified by the second argument. In this case, the function says to mask all elements of the array ytan (the second argument) where the absolute value of ytan is greater than 20. The result
is set equal to ytanM. When ytanM is plotted, matplotlib’s plot function omits all masked points from the plot. You can think of it as the plot function lifting the pen that is drawing the line in the plot when it comes to the masked points in the array ytanM.

The output is shown below:

Share:

0 comments:

Post a Comment