# graphing an equation with matplotlib

I'm trying to make a function that will graph whatever formula I tell it to.

```import numpy as np
import matplotlib.pyplot as plt
def graph(formula, x_range):
x = np.array(x_range)
y = formula
plt.plot(x, y)
plt.show()
```

When I try to call it the following error happens, I believe it's trying to do the multiplication before it gets to y = formula.

```graph(x**3+2*x-4, range(-10, 11))

Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
graph(x**3+2*x-4, range(-10, 11))
NameError: name 'x' is not defined
```

This is because in line

```graph(x**3+2*x-4, range(-10, 11))
```

x is not defined.

The easiest way is to pass the function you want to plot as a string and use eval to evaluate it as an expression.

So your code with minimal modifications will be

```import numpy as np
import matplotlib.pyplot as plt
def graph(formula, x_range):
x = np.array(x_range)
y = eval(formula)
plt.plot(x, y)
plt.show()
```

and you can call it as

```graph('x**3+2*x-4', range(-10, 11))
```

Your guess is right: the code is trying to evaluate x**3+2*x-4 immediately. Unfortunately you can't really prevent it from doing so. The good news is that in Python, functions are first-class objects, by which I mean that you can treat them like any other variable. So to fix your function, we could do:

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

def graph(formula, x_range):
x = np.array(x_range)
y = formula(x)  # <- note now we're calling the function 'formula' with x
plt.plot(x, y)
plt.show()

def my_formula(x):
return x**3+2*x-4

graph(my_formula, range(-10, 11))
```

If you wanted to do it all in one line, you could use what's called a lambda function, which is just a short function without a name where you don't use def or return:

```graph(lambda x: x**3+2*x-4, range(-10, 11))
```

And instead of range, you can look at np.arange (which allows for non-integer increments), and np.linspace, which allows you to specify the start, stop, and the number of points to use.

To plot an equation that is not solved for a specific variable (like circle or hyperbola):

```import numpy as np
import matplotlib.pyplot as plt
plt.figure() # Create a new figure window
xlist = np.linspace(-2.0, 2.0, 100) # Create 1-D arrays for x,y dimensions
ylist = np.linspace(-2.0, 2.0, 100)
X,Y = np.meshgrid(xlist, ylist) # Create 2-D grid xlist,ylist values
F = X**2 + Y**2 - 1  #  'Circle Equation
plt.contour(X, Y, F, , colors = 'k', linestyles = 'solid')
plt.show()
```