Nathaniel Weidman
Nathaniel Weidman

Reputation: 45

Plotting Derivatives With User-Defined Function

I want to plot the function x^-x along with it's derivatives. However the derivatives become tedious to write. Therefore I want to have Python find the derivatives for me and then plot them however I keep getting a syntax error. This is what I have so far.

import math 
import sympy as sp
import numpy as np 
import matplotlib.pyplot as plt
x,y,z = sp.symbols('x y z')

n=1 # order of derivative
def f(x):
   g=z**(-z)
   h=sp.diff(g,z,n)
   q=h.subs(z,x)
   return q

x1=np.arange(0,5,0.5)
plt.plot(x1,f(x1))
plt.show()

The full trackback of the error message is as follows:

SyntaxError                               Traceback (most recent call last)
C:\Users\Nathaniel\Anaconda3\lib\site-packages\sympy\core\sympify.py in 
sympify(a, locals, convert_xor, strict, rational, evaluate)
    321         a = a.replace('\n', '')
--> 322         expr = parse_expr(a, local_dict=locals, 
transformations=transformations, evaluate=evaluate)
    323     except (TokenError, SyntaxError) as exc:

C:\Users\Nathaniel\Anaconda3\lib\site-packages\sympy\parsing\sympy_parser.py 
in parse_expr(s, local_dict, transformations, global_dict, evaluate)
    893 
--> 894     return eval_expr(code, local_dict, global_dict)
    895 

C:\Users\Nathaniel\Anaconda3\lib\site-packages\sympy\parsing\sympy_parser.py 
in eval_expr(code, local_dict, global_dict)
    806     expr = eval(
--> 807         code, global_dict, local_dict)  # take local objects in 
    preference
    808 

SyntaxError: invalid syntax (<string>, line 1)

During handling of the above exception, another exception occurred:

SympifyError                              Traceback (most recent call last)
<ipython-input-2-13b1385304a2> in <module>()
     13 
     14 x1=np.arange(0,5,0.5)
---> 15 plt.plot(x1,f(x1))
     16 plt.show()

<ipython-input-2-13b1385304a2> in f(x)
      9     g=z**(-z)
     10     h=sp.diff(g,z,n)
---> 11     q=h.subs(z,x)
     12     return q
     13 

C:\Users\Nathaniel\Anaconda3\lib\site-packages\sympy\core\basic.py in 
subs(self, *args, **kwargs)
    851         for i in range(len(sequence)):
    852             o, n = sequence[i]
--> 853             so, sn = sympify(o), sympify(n)
    854             if not isinstance(so, Basic):
    855                 if type(o) is str:

C:\Users\Nathaniel\Anaconda3\lib\site-packages\sympy\core\sympify.py in 
sympify(a, locals, convert_xor, strict, rational, evaluate)
    322         expr = parse_expr(a, local_dict=locals, 
    transformations=transformations, evaluate=evaluate)
    323     except (TokenError, SyntaxError) as exc:
--> 324         raise SympifyError('could not parse %r' % a, exc)
    325 
    326     return expr

SympifyError: Sympify of expression 'could not parse '[ 0.   0.5  1.   1.5  
2.   2.5  3.   3.5  4.   4.5]'' failed, because of exception being raised:
SyntaxError: invalid syntax (<string>, line 1)

How would I get Python to plot this in a quick and efficient way?

Upvotes: 1

Views: 1254

Answers (1)

Mr. T
Mr. T

Reputation: 12410

It seems the differentiation functions in sympy are in the mpath library. Maybe there are other ways, how experienced sympy users can address the problem, but here is one solution:

import matplotlib.pyplot as plt
from mpmath import diff
from cycler import cycler
#create cycler objects that matplotlib uses as linestyles 
col = cycler("color", ["r", "b", "g"])
styl = cycler("linestyle", ["-", "-."])
plt.rc('axes', prop_cycle =  styl * col)

#define function to differentiate
def g(z):
    return z ** (-z)
#define the differentiation function
def f(xrange):
    return [diff(lambda x: g(x), xr, n) for xr in xrange]
#I prefer linspace over arange because you don't run into float point problems
x1 = np.linspace(1, 5, 100)
#cycle through derivative order
for n in range(5):
    plt.plot(x1, f(x1), label = "Order = {}".format(n))

plt.legend()
plt.show()

The line style of each function can be defined for instance by using cycler objects. There are of course other ways to control the colour of the lines in matplotlib.

Output:

enter image description here

Upvotes: 1

Related Questions