Reputation: 23
I am trying to create a 3d plot with sympy that has units, but I am getting different errors depending on where I try to type the units in. Below the units are built in the function itself, but I get an error also if I type the units into the plot axis variable: (a, 2.*meter/second^2., 0.*meter/second^2.), etc. I plunged through the Sympy documentation and couldn't find anything on plotting with units. Is there an established way to do this?
import matplotlib.pyplot as plt
from sympy.physics.units.systems.si import SI
from sympy.physics.units import second, newton, meter, kilogram
from sympy import init_printing
from sympy import *
from IPython.display import display
from sympy.plotting import plot3d
F, m, a = symbols('F_ m_ a_')
def F(a,m):
return a*(meter/second**2.)*m*kilogram
plot3d(F(a,m), (a, 2.,0.), (m, 0.,1.), zlabel=S('F_'))
I tried to use plot3d in sympy to plot a function with units, but it didn't work. I get either TypeError: Cannot convert the expression to float OR TypeError: cannot determine the truth value of Relational
Upvotes: 1
Views: 50
Reputation: 13150
Generally, you can't plot a symbolic expression containing units. Here is why.
When you create your expression with F(a,m)
, a
and m
are symbols. However, the expression also contains other entities, kilogram, meter, second
, which are instances of Quantity
(from sympy.physics.units
).
When you execute plot3d(F(a,m), (a, 2.,0.), (m, 0.,1.))
, this is what happens:
F(a,m)
generates a symbolic expression: kilogram*meter*a_*m_/second**2
lambdify
to convert that symbolic expression to a numerical function: f = lambdify([a, m], F(a,m))
. Let's look at it:
help(f)
Help on function _lambdifygenerated:
_lambdifygenerated(a_, m_)
Created with lambdify. Signature:
func(a_, m_)
Expression:
kilogram*meter*a_*m_/second**2
Source code:
def _lambdifygenerated(a_, m_):
return kilogram*meter*a_*m_/second**2
The numerical function has two parameters, a_, m_
, but it doesn't know what kilogram, meter, second
are.a_, m_
, provides them to the numerical function. At evaluation, you get those errors.Possible solution: remove the units from the symbolic expression. You can either rewrite your expression without units, or you can remove them with a substitution. Here is how:
from sympy.physics.units import Quantity
expr_with_units = F(a, m)
# create a substitution dictionary: replace each quantity with number 1
sd = {k: 1 for k in expr_with_units.find(Quantity)}
expr_without_units = expr_with_units.subs(sd)
plot3d(expr_without_units, (a, 0, 2), (m, 0, 1), zlabel=r"$kg \cdot m / s^2$")
Upvotes: 1