Reputation: 1
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
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