Tayyab Khalil
Tayyab Khalil

Reputation: 1

Plotting derivative of expnential in python - any idea what i'm doing wrong?

Here's the code: importing stuff

import numpy as np
import sympy as sp
from sympy import symbols, diff

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt

defining function and it's derivative

t = symbols('t')
B = sp.exp(t)

f = sp.diff(B, t)

print(f)

plot settings

fig1 = plt.figure(1)
ax1 = fig1.gca(projection='3d')

x, t, z = np.meshgrid(np.linspace(-4, 4, 15),
                  np.linspace(0, 4, 10),
                  np.linspace(-4, 4, 15))

u = 0
v = 0
ax1.quiver(x, t, z, u, v, f, length = 0.07)

plt.show()

I keep getting the "can't convert to float" error, the program does print the derivative though and plots too when used without the derivative...

Upvotes: 0

Views: 137

Answers (1)

hpaulj
hpaulj

Reputation: 231605

Here's the traceback:

In [8]: ax1.quiver(x, t, z, u, v, f, length = 0.07)                             
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-66e3c3d2c6bf> in <module>
----> 1 ax1.quiver(x, t, z, u, v, f, length = 0.07)

/usr/local/lib/python3.6/dist-packages/mpl_toolkits/mplot3d/axes3d.py in quiver(self, length, arrow_length_ratio, pivot, normalize, *args, **kwargs)
   2620 
   2621         XYZ = np.column_stack(input_args[:3])
-> 2622         UVW = np.column_stack(input_args[3:argi]).astype(float)
   2623 
   2624         # Normalize rows of UVW

/usr/local/lib/python3.6/dist-packages/sympy/core/expr.py in __float__(self)
    278         if result.is_number and result.as_real_imag()[1]:
    279             raise TypeError("can't convert complex to float")
--> 280         raise TypeError("can't convert expression to float")
    281 
    282     def __complex__(self):

TypeError: can't convert expression to float

Apparently it's trying to turn the u,v,f arguments into a numeric array.

In [9]: np.column_stack([u,v,f])                                                
Out[9]: array([[0, 0, exp(t)]], dtype=object)

float(exp(t)) doesn't work. f is a sympy expression; you can't turn it into a number.

The underlying problem is that you are trying to use a numeric plotting function to plot a symbolic expression. sympy and numpy don't work together seamlessly. Either use sympy's plotting tools, or convert your expression to a numeric one - an array of numbers evaluated at some points.

===

ax1.quiver(x, t, z, u, v, np.exp(t), length = 0.07) 

does run. np.exp(t) is an array, the same size as t.

===

Sympy plotting:

In [12]: from sympy.plotting import plot                                        

In [13]: plot(f)                                                                
Out[13]: <sympy.plotting.plot.Plot at 0x7f02b0f99400>

https://docs.sympy.org/latest/modules/plotting.html

===

https://docs.sympy.org/latest/tutorial/basic_operations.html#lambdify

lambdify is a sympy tool for bridging the gap between sympy and numpy. It generates a numpy (as default) function from the sympy expression:

In [27]: fn=lambdify(symbols('t'),f)                                            

In [28]: fn                                                                     
Out[28]: <function _lambdifygenerated(t)>

In [29]: fn(t).shape     # evaluate a the 3d array `t`                                                            
Out[29]: (10, 15, 15)

Now we have numeric array that works in quiver:

In [36]: ax1.quiver(x, t, z, u, v, fn(t), length = 0.07)                        
Out[36]: <mpl_toolkits.mplot3d.art3d.Line3DCollection at 0x7f02b0f24e80>

Upvotes: 1

Related Questions