0

Two questions related to plotting and the below user defined functions. By way of background, this is the first time I've seen plt.plot called inside a for loop such that each point is plotted individually. I'm used to seeing entire arrays passed as arguments such as in plt.plot(x, f(x)). My first question is what is the benefit of iterating over each point and calling plt.plot each time? Is there some additional control over the plot by using this method as opposed to calling plt.plot(x, f(x)) and passing all the points once?

My second question is with regard to the styles parameter in the below function. I’m unsure how or why indexing into a list containing a single character works? styles = [‘b’] is a list containing a single character. So my expectation is that any slicing/indexing with an argument other than 0, would raise an exception. In other words, I would expect that when the for loop index exceeds 0 (e.g. styles[1], styles [2], etc.) then an exception would be thrown. What am I missing?

import numpy as np
from pylab import plt, mpl
plt.style.use('seaborn')
mpl.rcParams['font.family'] = 'serif'
%matplotlib inline

def f(x):
    return np.sin(x) + 0.5 * x

def create_plot(x, y, styles, labels, axlabels):
    plt.figure(figsize=(10, 6))
    for i in range(len(x)):
        plt.plot(x[i], y[i], styles[i], label=labels[i])
        plt.xlabel(axlabels[0])
        plt.ylabel(axlabels[1])
        plt.legend(loc=0)

x = np.linspace(-2 * np.pi, 2 * np.pi, 50)

create_plot([x], [f(x)], ['b'], ['f(x)'], ['x', 'f(x)'])
jgg
  • 791
  • 4
  • 17

2 Answers2

0

You seem to be confusing the global parameter x which is an array of points with the function parameter x which is a list of arrays (of points). So, both xs represent a quite different concept. The code below renames the function parameters to avoid some of the confusion. Also, nowadays pylab is usually replaced by matplotlib.

The main idea of the function is that x, y, styles and labels in general would have multiple elements. These are four lists that should have the same number of elements. In the original example there is just one element in each.

The online documentation of the plot command has an extensive overview of parameter strings for the style. For example 'b' is just a blue line. -r* is red and has stars for each vertex, connected with full lines. g: indicates a dotted green line. Etc.

Here is an example drawing 3 functions:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

plt.style.use('seaborn')
mpl.rcParams['font.family'] = 'serif'

def f(x):
    return np.sin(x) + 0.5 * x

def create_plot(xs, ys, styles, labels, axlabels):
    plt.figure(figsize=(10, 6))
    for i in range(len(xs)):
        plt.plot(xs[i], ys[i], styles[i], label=labels[i])
        plt.xlabel(axlabels[0])
        plt.ylabel(axlabels[1])
        plt.legend(loc=0)

x = np.linspace(-2 * np.pi, 2 * np.pi, 50)
create_plot([x, x, x], [f(x), np.cos(x), x * x / 20], ['b', '-r*', 'g:'],
            ['f(x)', 'cos(x)', 'x^2 / 20'], ['x', 'f(x)'])
plt.show()

example plot

JohanC
  • 71,591
  • 8
  • 33
  • 66
0

After thinking about this a bit more, I was able to resolve the second question. I didn't realize that [x] is a list of length 1 so the for loop only iterates once and therefore there's no conflict with styles = ['b'] since the only value of i that's realized is 0.

jgg
  • 791
  • 4
  • 17