Ask Your Question
0

StreamPlot error "ndim" is not an attribute

asked 2023-04-09 07:21:09 +0100

E Net Arch gravatar image

import numpy as np import matplotlib.pyplot as plt import math as Math

Q = 1 #Columb
E0 = 8.854187817e-12
K = 1/ (4 * Math.pi * E0)

gridx = np.arange(-5,5,0.1)
gridy = np.arange(-5,5,0.1)

x,y = np.meshgrid (gridx, gridy)

eqn(x,y) = K*Q / (x**2 + y**2)^(1/2)

grad = vector ( [ diff(eqn,x), diff(eqn,y) ] )
Ex = diff (eqn, x)
Ey = diff (eqn, y)

U = (K*Q * x) / (x**2 + y**2)^(3/2)
V = (K*Q * y) / (x**2 + y**2)^(3/2)

plt.figure (figsize = (10, 10))
plt.streamplot (grad, x,y, color='green')
plt.streamplot (x,y, Ex,Ey, color='green')
plt.streamplot (x,y, U,V, color='green')
plt.grid()
plt.show()

Each version produces a different error, I don't understand why. And, I want to know why!

#1 .. missing required positional argument v

#2 .. ndim is not an attribute

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
1

answered 2023-04-10 00:07:56 +0100

Emmanuel Charpentier gravatar image

As asked, your question does not use any Sage specific function and uses Sage as a Python interpreter. It would probably better aimed at a Python list/forum.

But Sage has functions useful for this task. Given :

sage: var("Q,E0")
(Q, E0)
sage: K=1/(4*pi*E0) # Keep constant's definition.
sage: NumVals={Q:1,E0:8.854187817e-12} # Separate symbolic and numeric computations...
sage: f(x,y)=K*Q/sqrt(x^2+y^2) # define f symbolically.

You may compute :

sage: f.gradient()
(x, y) |--> (-1/4*Q*x/(pi*(x^2 + y^2)^(3/2)*E0), -1/4*Q*y/(pi*(x^2 + y^2)^(3/2)*E0))

i. e. a symbolic function of two variables returning a bidimensional vector, better typeset as :

$$ \left( x, y \right) \ {\mapsto} \ \left(-\frac{Q x}{4 \, \pi {\left(x^{2} + y^{2}\right)}^{\frac{3}{2}} E_{0}},\,-\frac{Q y}{4 \, \pi {\left(x^{2} + y^{2}\right)}^{\frac{3}{2}} E_{0}}\right) $$

Graphing needs numerical values, but having them in a dictionary allows to keep the working tools (definitions, equations, intermediate results...) symbolic (i. e. understandable) until numerical values are needed.

I'm not sure what Matplotlib's streamplot is supposed to do. I suppose its either :

sage: streamline_plot(f.gradient().subs(NumVals).list(), (-5, 5), (-5, 5))
Launched png viewer for Graphics object consisting of 1 graphics primitive

image description

or, possibly,

sage: plot_vector_field(f.gradient().subs(NumVals), (x, -5, 5), (y, -5, 5))
Launched png viewer for Graphics object consisting of 1 graphics primitive

image description

HTH,

edit flag offensive delete link more

Comments

I was able to get streamline_plot and plot_vector_field to work. The original code should work, but even you avoided using it to answer the question, which raises the question, "Why doesn't it work?" But thanks for providing the alternatives to others having difficulty with streampliot who need alternatives to complete the task.

E Net Arch gravatar imageE Net Arch ( 2023-04-10 02:05:03 +0100 )edit
1

answered 2023-04-10 03:52:25 +0100

I think the problem is that you're trying to mix numpy and matplotlib and Sage in ways that are not supported. The documentation for plt.streamplot says:

Parameters
**********

x, y : 1D/2D arrays
   Evenly spaced strictly increasing arrays to make a grid.  If 2D,
   all rows of *x* must be equal and all columns of *y* must be equal;
   i.e., they must be as if generated by "np.meshgrid(x_1d, y_1d)".

u, v : 2D arrays
   *x* and *y*-velocities. The number of rows and columns must match
   the length of *y* and *x*, respectively.

It looks like you're trying to pass grid in the place of both x and y, but grid is a function, not a pair of arrays of values. You also define x and y using np.meshgrid, but the later assignment eqn(x,y) = K*Q / (x**2 + y**2)^(1/2) redefines x and y to be symbolic variables. I suggest instead:

xx,yy = np.meshgrid (gridx, gridy) # don't redefine x and y

and

G = [grad(x,y) for (x,y) in zip(gridx,gridy)]
Gx = [a[0] for a in G]
Gy = [a[1] for a in G]

and finally

plt.streamplot (Gx, Gy, xx,yy, color='green')

This doesn't work, either, but the error message is different. Maybe you need to do more conversion to get xx and Gx in the same format (convert both to floats? convert Gx to a numpy array?).

edit flag offensive delete link more

Comments

Thanks you for this attempt. The working examples that I found for streamplot actually used most of the code that I provided. Their method of managing the equation though was different.

https://www.geeksforgeeks.org/matplotlib-pyplot-streamplot-in-python/ (https://www.geeksforgeeks.org/matplot...)

E Net Arch gravatar imageE Net Arch ( 2023-04-10 05:39:40 +0100 )edit

The equation is the whole issue: a symbolic expression, like your grad, is not something that matplotlib is designed to handle. I think you need an array of values, not an expression.

John Palmieri gravatar imageJohn Palmieri ( 2023-04-10 06:19:03 +0100 )edit

@John Palmieri, I thought of that, that's why I included 3 different examples of streamplot using the equations. 2 where it was derived through sagemath by 2 different methods, and 1 where I provided the derivative directly as U and V. This didn't make the code work either. More suggestions?

E Net Arch gravatar imageE Net Arch ( 2023-04-10 06:58:35 +0100 )edit

type(U) returns <class 'sage.symbolic.expression.Expression'>, and the same with type(Ex). It's the same problem each time: you need an array, not a symbolic expression.

John Palmieri gravatar imageJohn Palmieri ( 2023-04-10 17:46:07 +0100 )edit

@John Plamieri, thanks for the information on the expressions. I'll have to look at example 2 of the URL provided above to see if it's producing the same results concerning U and V. Though, I feel, that regardless of the results, streamplot should use the equations as they are. I'm not sure who to push that feature request to, though.

E Net Arch gravatar imageE Net Arch ( 2023-04-11 21:32:43 +0100 )edit
0

answered 2023-04-12 05:16:08 +0100

E Net Arch gravatar image
import numpy as np
import matplotlib.pyplot as plt
import math as Math

Q = 1 #Columb
E0 = 8.854187817e-12
K = 1/ (4 * Math.pi * E0)

gridx = np.arange(-5,5,0.1)
gridy = np.arange(-5,5,0.1)

x,y = np.meshgrid (gridx, gridy)

U = (K*Q * x) / (x**2 + y**2)^(3/2)
V = (K*Q * y) / (x**2 + y**2)^(3/2)

# eqn(x,y) = K*Q / (x**2 + y**2)^(1/2)
# grad = vector ( [ diff(eqn,x), diff(eqn,y) ] )
# Ex = diff (eqn, x)
# Ey = diff (eqn, y)

plt.figure (figsize = (10, 10))
#plt.streamplot (grad, x,y, color='green')
#plt.streamplot (x,y, Ex,Ey, color='green')
plt.streamplot (x,y, U,V, color='green')
plt.grid()
plt.show()

So, out of curiosity I attempted to convert the symbolic expression to a numpy array, and didn't find a conversion routine.

The other thing I did, was re-arrange the order of the equations and REM out the lines using the variable eqn. It appears that this one line converted the variables (x,y) to symbolic variables. I consider this to be a major failing of SageMath for not tattling, and for throwing other errors when the variables associated with eqn are passed to streamplot. I also consider it a major failing of streamplot that it can't use symbolic expressions.

So, the fix, is to not use symbolic equations with streamplot, at least and until streamplot updates their code to accommodate symbolic equations.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2023-04-09 07:15:25 +0100

Seen: 728 times

Last updated: Apr 12 '23