ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Fri, 30 Dec 2016 18:54:07 +0100Plotting 2d vector fields – how to delay function evaluationhttps://ask.sagemath.org/question/36127/plotting-2d-vector-fields-how-to-delay-function-evaluation/I want to plot, for example, the following 2d vector field:
$$\vec{F}(x,y)= \begin{cases}
(0.1,0.1), & \text{for }r\le d_{min}\newline
\frac{\vec{r}}{r^3}, & \text{otherwise}.
\end{cases}$$
In one SageMath cell I have defined corresponding Python function:
reset()
dmin = 0.03
def my_vector_field_2D(x,y):
vector_field = vector([0.1,0.1])
r = vector([x,y])
if r.norm()>dmin:
vector_field = 1/ r.norm()^3 * r
return vector_field
In another cell, I use function `plot_vector_field` to plot the field:
var('x','y')
plot_vector_field(my_vector_field_2D(x,y),(x,-0.3,0.3),(y,-0.3,0.3))
However, function my_vector_field_2D(x,y) is evaluated before it is given to the function `plot_vector_field` and because in this evaluation my_vector_field_2D receives instead of numbers symbolic variables `x` and `y`, expression `r.norm()>dmin` is always `False`. As a result, my_vector_field_2D(x,y) is evalueted to: (0.100000000000000, 0.100000000000000). So the plotted filed is actually $\vec{F}(x,y)=(0.1,0.1)$ everywhere and that is not what I want.
How can I prevent this function evaluation?
I tried something that works with the `plot` function (provide the `plot` function with just the name of a function that you want to plot (without parameters) in order to prevent function evaluation):
plot_vector_field(my_vector_field_2D,(-0.3,0.3),(-0.3,0.3))
But here this method does not work: **TypeError**: 'function' object is not iterable.
**My first why question**: Why this does not work? It works for `plot` function and also for `contour_plot` function and probably for some other plot functions.
Then I found in the SageMath documentation that “when plotting non-symbolic functions, they should be wrapped in `lambda`”. So I tried:
plot_vector_field(lambda x,y:my_vector_field_2D(x,y),(-0.3,0.3),(-0.3,0.3))
And the same error popped up: **TypeError**: 'function' object is not iterable.
But this works:
plot_vector_field((lambda x,y:my_vector_field_2D(x,y)[0],lambda x,y:my_vector_field_2D(x,y)[1]),(-0.3,0.3),(-0.3,0.3))
**My second why question**: Why do I need two `lambda` functions or why do I need to manually decompose vector returned by my_vector_field_2D function into its two components?
vkFri, 30 Dec 2016 18:54:07 +0100https://ask.sagemath.org/question/36127/