Ask Your Question

Revision history [back]

Simply use the method chart to define your own version of spherical coordinates and then relate them to Sage's default spherical coordinates via the method transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: Ec.coord_range()                                                                              
r: (0, +oo); theta: [0, 2*pi] (periodic); phi: (-1/2*pi, 1/2*pi)
sage: Ec0.<r,theta0,phi0> = E.spherical_coordinates()       # the default spherical coordinates                                        
sage: Ec0_to_Ec = Ec0.transition_map(Ec, (r, phi0, pi/2 - theta0))                                  
sage: Ec0_to_Ec.display()                                                                           
r = r
theta = phi0
phi = 1/2*pi - theta0
sage: Ec0_to_Ec.inverse().display()                                                                 
r = r
theta0 = 1/2*pi - phi
phi0 = theta
sage: E.set_default_chart(Ec)                                                                       
sage: E.set_default_frame(Ec.frame())

Then you can relate your spherical coordinates to the Cartesian ones as follows:

sage: Ec_to_cart = E.coord_change(Ec0, E.cartesian_coordinates()) * Ec0_to_Ec.inverse()             
sage: Ec_to_cart.display()                                                                          
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

See E.chart? and Ec0.transition_map? for more details.

Simply use the method chart to define your own version of spherical coordinates and then relate them to Sage's default spherical coordinates via the method transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: Ec.coord_range()                                                                              
r: (0, +oo); theta: [0, 2*pi] (periodic); phi: (-1/2*pi, 1/2*pi)
sage: Ec0.<r,theta0,phi0> = E.spherical_coordinates()       # the default spherical coordinates                                        
sage: Ec0_to_Ec = Ec0.transition_map(Ec, (r, phi0, pi/2 - theta0))                                  
sage: Ec0_to_Ec.display()                                                                           
r = r
theta = phi0
phi = 1/2*pi - theta0
sage: Ec0_to_Ec.inverse().display()                                                                 
r = r
theta0 = 1/2*pi - phi
phi0 = theta
sage: E.set_default_chart(Ec)                                                                       
sage: E.set_default_frame(Ec.frame())

Then you can relate your spherical coordinates to the Cartesian ones as follows:

sage: Ec_to_cart = E.coord_change(Ec0, E.cartesian_coordinates()) * Ec0_to_Ec.inverse()             
sage: Ec_to_cart.display()                                                                          
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

See E.chart? and Ec0.transition_map? for more details.

EDIT:

Another option is not to use Sage's standard spherical coordinates, but link your spherical coordinates directly to the Cartesian ones via transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: E.set_default_chart(Ec)                                                                                          
sage: E.set_default_frame(Ec.frame())                                                                                  
sage: cart = E.cartesian_coordinates()                                                              
sage: Ec_to_cart = Ec.transition_map(cart, (r*cos(theta)*cos(phi), r*sin(theta)*cos(phi), r*sin(phi)))                 
sage: Ec_to_cart.display()                                                                                             
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

To complete the relation to Cartesian coordinates, you have to provide the inverse transition map (it is too involved for Sage to compute it automatically via the method inverse()). This is done by means of set_inverse:

sage: Ec_to_cart.set_inverse(sqrt(x^2 + y^2 + z^2), atan2(y, x), atan(z/sqrt(x^2 + y^2)))                              
Check of the inverse coordinate transformation:
  r == r  *passed*
  theta == arctan2(r*cos(phi)*sin(theta), r*cos(phi)*cos(theta))  **failed**
  phi == arctan(sin(phi)/cos(phi))  **failed**
  x == x  *passed*
  y == y  *passed*
  z == z  *passed*
NB: a failed report can reflect a mere lack of simplification.

You have then:

sage: Ec_to_cart.inverse().display()                                                                                   
r = sqrt(x^2 + y^2 + z^2)
theta = arctan2(y, x)
phi = arctan(z/sqrt(x^2 + y^2))

As a check that everything goes well with your version of spherical coordinates, you can ask Sage to display the Euclidean metric:

sage: E.metric().display()                                                                                             
g = dr*dr + r^2*cos(phi)^2 dtheta*dtheta + r^2 dphi*dphi

Simply use the method chart to define your own version of spherical coordinates and then relate them to Sage's default spherical coordinates via the method transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: Ec.coord_range()                                                                              
r: (0, +oo); theta: [0, 2*pi] (periodic); phi: (-1/2*pi, 1/2*pi)
sage: Ec0.<r,theta0,phi0> = E.spherical_coordinates()       # the default spherical coordinates                                        
sage: Ec0_to_Ec = Ec0.transition_map(Ec, (r, phi0, pi/2 - theta0))                                  
sage: Ec0_to_Ec.display()                                                                           
r = r
theta = phi0
phi = 1/2*pi - theta0
sage: Ec0_to_Ec.inverse().display()                                                                 
r = r
theta0 = 1/2*pi - phi
phi0 = theta
sage: E.set_default_chart(Ec)                                                                       
sage: E.set_default_frame(Ec.frame())

Then you can relate your spherical coordinates to the Cartesian ones as follows:

sage: Ec_to_cart = E.coord_change(Ec0, E.cartesian_coordinates()) * Ec0_to_Ec.inverse()             
sage: Ec_to_cart.display()                                                                          
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

See E.chart? and Ec0.transition_map? for more details.

EDIT:

Another option is not to use Sage's standard spherical coordinates, but link your spherical coordinates directly to the Cartesian ones via transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: E.set_default_chart(Ec)                                                                                          
sage: E.set_default_frame(Ec.frame())                                                                                  
sage: cart = E.cartesian_coordinates()                                                              
sage: Ec_to_cart = Ec.transition_map(cart, (r*cos(theta)*cos(phi), r*sin(theta)*cos(phi), r*sin(phi)))                 
sage: Ec_to_cart.display()                                                                                             
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

To complete the relation to Cartesian coordinates, you have to provide the inverse transition map (it is too involved for Sage to compute it automatically via the method inverse()). This is done by means of set_inverse:

sage: Ec_to_cart.set_inverse(sqrt(x^2 + y^2 + z^2), atan2(y, x), atan(z/sqrt(x^2 + y^2)))                              
Check of the inverse coordinate transformation:
  r == r  *passed*
  theta == arctan2(r*cos(phi)*sin(theta), r*cos(phi)*cos(theta))  **failed**
  phi == arctan(sin(phi)/cos(phi))  **failed**
  x == x  *passed*
  y == y  *passed*
  z == z  *passed*
NB: a failed report can reflect a mere lack of simplification.

You have then:

sage: Ec_to_cart.inverse().display()                                                                                   
r = sqrt(x^2 + y^2 + z^2)
theta = arctan2(y, x)
phi = arctan(z/sqrt(x^2 + y^2))

As a check that everything goes well with your version of spherical coordinates, you can ask Sage to display the Euclidean metric:

sage: E.metric().display()                                                                                             
g = dr*dr + r^2*cos(phi)^2 dtheta*dtheta + r^2 dphi*dphi

EDIT 2: orthonormal frame associated with the customized spherical coordinates

One may introduce the orthonormal frame $(e_r, e_{\theta}, e_{\phi})$ such that $e_r = \partial/\partial r$, $e_\theta = \frac{1}{r\cos\phi} \partial/\partial\theta$, $e_\phi = 1/r \partial/\partial\phi$, as follows:

sage: e1 = E.vector_field(1, 0, 0, name='e_r')                                                      
sage: e1.display()                                                                                  
e_r = d/dr
sage: e2 = E.vector_field(0, 1/(r*cos(phi)), 0, name='e_theta')                                     
sage: e2.display()                                                                                  
e_theta = 1/(r*cos(phi)) d/dtheta
sage: e3 = E.vector_field(0, 0, 1/r, name='e_phi')                                                  
sage: e3.display()                                                                                  
e_phi = 1/r d/dphi
sage: e = E.vector_frame('e', (e1, e2, e3))

Then:

sage: for v in e: 
....:     v.display(Ec.frame()) 
....:                                                                                               
e_1 = d/dr
e_2 = 1/(r*cos(phi)) d/dtheta
e_3 = 1/r d/dphi
sage: for v in e: 
....:     v.display(cart.frame()) 
....:                                                                                               
e_1 = cos(phi)*cos(theta) e_x + cos(phi)*sin(theta) e_y + sin(phi) e_z
e_2 = -sin(theta) e_x + cos(theta) e_y
e_3 = -cos(theta)*sin(phi) e_x - sin(phi)*sin(theta) e_y + cos(phi) e_z

The dual coframe is

sage: e.coframe()                                                                                   
Coframe (E^3, (e^1,e^2,e^3))
sage: for f in e.coframe(): 
....:     f.display(Ec.frame()) 
....:                                                                                               
e^1 = dr
e^2 = r*cos(phi) dtheta
e^3 = r dphi

We check that e is an orthonormal frame:

sage: E.metric().display(e)                                                                         
g = e^1*e^1 + e^2*e^2 + e^3*e^3
sage: E.metric()[e,:]                                                                               
[1 0 0]
[0 1 0]
[0 0 1]

and set it to the default frame on the Euclidean space:

sage: E.set_default_frame(e)

Simply use the method chart to define your own version of spherical coordinates and then relate them to Sage's default spherical coordinates via the method transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: Ec.coord_range()                                                                              
r: (0, +oo); theta: [0, 2*pi] (periodic); phi: (-1/2*pi, 1/2*pi)
sage: Ec0.<r,theta0,phi0> = E.spherical_coordinates()       # the default spherical coordinates                                        
sage: Ec0_to_Ec = Ec0.transition_map(Ec, (r, phi0, pi/2 - theta0))                                  
sage: Ec0_to_Ec.display()                                                                           
r = r
theta = phi0
phi = 1/2*pi - theta0
sage: Ec0_to_Ec.inverse().display()                                                                 
r = r
theta0 = 1/2*pi - phi
phi0 = theta
sage: E.set_default_chart(Ec)                                                                       
sage: E.set_default_frame(Ec.frame())

Then you can relate your spherical coordinates to the Cartesian ones as follows:

sage: Ec_to_cart = E.coord_change(Ec0, E.cartesian_coordinates()) * Ec0_to_Ec.inverse()             
sage: Ec_to_cart.display()                                                                          
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

See E.chart? and Ec0.transition_map? for more details.

EDIT:

Another option is not to use Sage's standard spherical coordinates, but link your spherical coordinates directly to the Cartesian ones via transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: E.set_default_chart(Ec)                                                                                          
sage: E.set_default_frame(Ec.frame())                                                                                  
sage: cart = E.cartesian_coordinates()                                                              
sage: Ec_to_cart = Ec.transition_map(cart, (r*cos(theta)*cos(phi), r*sin(theta)*cos(phi), r*sin(phi)))                 
sage: Ec_to_cart.display()                                                                                             
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

To complete the relation to Cartesian coordinates, you have to provide the inverse transition map (it is too involved for Sage to compute it automatically via the method inverse()). This is done by means of set_inverse:

sage: Ec_to_cart.set_inverse(sqrt(x^2 + y^2 + z^2), atan2(y, x), atan(z/sqrt(x^2 + y^2)))                              
Check of the inverse coordinate transformation:
  r == r  *passed*
  theta == arctan2(r*cos(phi)*sin(theta), r*cos(phi)*cos(theta))  **failed**
  phi == arctan(sin(phi)/cos(phi))  **failed**
  x == x  *passed*
  y == y  *passed*
  z == z  *passed*
NB: a failed report can reflect a mere lack of simplification.

You have then:

sage: Ec_to_cart.inverse().display()                                                                                   
r = sqrt(x^2 + y^2 + z^2)
theta = arctan2(y, x)
phi = arctan(z/sqrt(x^2 + y^2))

As a check that everything goes well with your version of spherical coordinates, you can ask Sage to display the Euclidean metric:

sage: E.metric().display()                                                                                             
g = dr*dr + r^2*cos(phi)^2 dtheta*dtheta + r^2 dphi*dphi

EDIT 2: orthonormal frame associated with the customized spherical coordinates

One may introduce the orthonormal frame $(e_r, e_{\theta}, e_{\phi})$ such that $e_r = \partial/\partial r$, \frac{\partial}{\partial r}$, $e_\theta = \frac{1}{r\cos\phi} \partial/\partial\theta$, \frac{\partial}{\partial\theta}$, $e_\phi = 1/r \partial/\partial\phi$, \frac{1}{r}\frac{\partial}{\partial\phi}$, as follows:

sage: e1 = E.vector_field(1, 0, 0, name='e_r')                                                      
sage: e1.display()                                                                                  
e_r = d/dr
sage: e2 = E.vector_field(0, 1/(r*cos(phi)), 0, name='e_theta')                                     
sage: e2.display()                                                                                  
e_theta = 1/(r*cos(phi)) d/dtheta
sage: e3 = E.vector_field(0, 0, 1/r, name='e_phi')                                                  
sage: e3.display()                                                                                  
e_phi = 1/r d/dphi
sage: e = E.vector_frame('e', (e1, e2, e3))

Then:

sage: for v in e: 
....:     v.display(Ec.frame()) 
....:                                                                                               
e_1 = d/dr
e_2 = 1/(r*cos(phi)) d/dtheta
e_3 = 1/r d/dphi
sage: for v in e: 
....:     v.display(cart.frame()) 
....:                                                                                               
e_1 = cos(phi)*cos(theta) e_x + cos(phi)*sin(theta) e_y + sin(phi) e_z
e_2 = -sin(theta) e_x + cos(theta) e_y
e_3 = -cos(theta)*sin(phi) e_x - sin(phi)*sin(theta) e_y + cos(phi) e_z

The dual coframe is

sage: e.coframe()                                                                                   
Coframe (E^3, (e^1,e^2,e^3))
sage: for f in e.coframe(): 
....:     f.display(Ec.frame()) 
....:                                                                                               
e^1 = dr
e^2 = r*cos(phi) dtheta
e^3 = r dphi

We check that e is an orthonormal frame:

sage: E.metric().display(e)                                                                         
g = e^1*e^1 + e^2*e^2 + e^3*e^3
sage: E.metric()[e,:]                                                                               
[1 0 0]
[0 1 0]
[0 0 1]

and set it to the default frame on the Euclidean space:

sage: E.set_default_frame(e)

Simply use the method chart to define your own version of spherical coordinates and then relate them to Sage's default spherical coordinates via the method transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: Ec.coord_range()                                                                              
r: (0, +oo); theta: [0, 2*pi] (periodic); phi: (-1/2*pi, 1/2*pi)
sage: Ec0.<r,theta0,phi0> = E.spherical_coordinates()       # the default spherical coordinates                                        
sage: Ec0_to_Ec = Ec0.transition_map(Ec, (r, phi0, pi/2 - theta0))                                  
sage: Ec0_to_Ec.display()                                                                           
r = r
theta = phi0
phi = 1/2*pi - theta0
sage: Ec0_to_Ec.inverse().display()                                                                 
r = r
theta0 = 1/2*pi - phi
phi0 = theta
sage: E.set_default_chart(Ec)                                                                       
sage: E.set_default_frame(Ec.frame())

Then you can relate your spherical coordinates to the Cartesian ones as follows:

sage: Ec_to_cart = E.coord_change(Ec0, E.cartesian_coordinates()) * Ec0_to_Ec.inverse()             
sage: Ec_to_cart.display()                                                                          
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

See E.chart? and Ec0.transition_map? for more details.

EDIT:

Another option is not to use Sage's standard spherical coordinates, but link your spherical coordinates directly to the Cartesian ones via transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: E.set_default_chart(Ec)                                                                                          
sage: E.set_default_frame(Ec.frame())                                                                                  
sage: cart = E.cartesian_coordinates()                                                              
sage: Ec_to_cart = Ec.transition_map(cart, (r*cos(theta)*cos(phi), r*sin(theta)*cos(phi), r*sin(phi)))                 
sage: Ec_to_cart.display()                                                                                             
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

To complete the relation to Cartesian coordinates, you have to provide the inverse transition map (it is too involved for Sage to compute it automatically via the method inverse()). This is done by means of set_inverse:

sage: Ec_to_cart.set_inverse(sqrt(x^2 + y^2 + z^2), atan2(y, x), atan(z/sqrt(x^2 + y^2)))                              
Check of the inverse coordinate transformation:
  r == r  *passed*
  theta == arctan2(r*cos(phi)*sin(theta), r*cos(phi)*cos(theta))  **failed**
  phi == arctan(sin(phi)/cos(phi))  **failed**
  x == x  *passed*
  y == y  *passed*
  z == z  *passed*
NB: a failed report can reflect a mere lack of simplification.

You have then:

sage: Ec_to_cart.inverse().display()                                                                                   
r = sqrt(x^2 + y^2 + z^2)
theta = arctan2(y, x)
phi = arctan(z/sqrt(x^2 + y^2))

As a check that everything goes well with your version of spherical coordinates, you can ask Sage to display the Euclidean metric:

sage: E.metric().display()                                                                                             
g = dr*dr + r^2*cos(phi)^2 dtheta*dtheta + r^2 dphi*dphi

EDIT 2: orthonormal frame associated with the customized spherical coordinates

One may introduce the orthonormal frame $(e_r, e_{\theta}, e_{\phi})$ such that $e_r = \frac{\partial}{\partial r}$, $e_\theta = \frac{1}{r\cos\phi} \frac{\partial}{\partial\theta}$, $e_\phi = \frac{1}{r}\frac{\partial}{\partial\phi}$, as follows:

sage: e1 = E.vector_field(1, 0, 0, name='e_r')                                                      
sage: e1.display()                                                                                  
e_r = d/dr
sage: e2 = E.vector_field(0, 1/(r*cos(phi)), 0, name='e_theta')                                     
sage: e2.display()                                                                                  
e_theta = 1/(r*cos(phi)) d/dtheta
sage: e3 = E.vector_field(0, 0, 1/r, name='e_phi')                                                  
sage: e3.display()                                                                                  
e_phi = 1/r d/dphi
sage: e = E.vector_frame('e', (e1, e2, e3))

Then:

sage: for v in e: 
....:     v.display(Ec.frame()) 
....:                                                                                               
e_1 = d/dr
e_2 = 1/(r*cos(phi)) d/dtheta
e_3 = 1/r d/dphi
sage: for v in e: 
....:     v.display(cart.frame()) 
....:                                                                                               
e_1 = cos(phi)*cos(theta) e_x + cos(phi)*sin(theta) e_y + sin(phi) e_z
e_2 = -sin(theta) e_x + cos(theta) e_y
e_3 = -cos(theta)*sin(phi) e_x - sin(phi)*sin(theta) e_y + cos(phi) e_z

The dual coframe is

sage: e.coframe()                                                                                   
Coframe (E^3, (e^1,e^2,e^3))
sage: for f in e.coframe(): 
....:     f.display(Ec.frame()) 
....:                                                                                               
e^1 = dr
e^2 = r*cos(phi) dtheta
e^3 = r dphi

We check that e is an orthonormal frame:

sage: E.metric().display(e)                                                                         
g = e^1*e^1 + e^2*e^2 + e^3*e^3
sage: E.metric()[e,:]                                                                               
[1 0 0]
[0 1 0]
[0 0 1]

and set use it to as the default vector frame on the Euclidean space:space E:

sage: E.set_default_frame(e)

Simply use the method chart to define your own version of spherical coordinates and then relate them to Sage's default spherical coordinates via the method transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: Ec.coord_range()                                                                              
r: (0, +oo); theta: [0, 2*pi] (periodic); phi: (-1/2*pi, 1/2*pi)
sage: Ec0.<r,theta0,phi0> = E.spherical_coordinates()       # the default spherical coordinates                                        
sage: Ec0_to_Ec = Ec0.transition_map(Ec, (r, phi0, pi/2 - theta0))                                  
sage: Ec0_to_Ec.display()                                                                           
r = r
theta = phi0
phi = 1/2*pi - theta0
sage: Ec0_to_Ec.inverse().display()                                                                 
r = r
theta0 = 1/2*pi - phi
phi0 = theta
sage: E.set_default_chart(Ec)                                                                       
sage: E.set_default_frame(Ec.frame())

Then you can relate your spherical coordinates to the Cartesian ones as follows:

sage: Ec_to_cart = E.coord_change(Ec0, E.cartesian_coordinates()) * Ec0_to_Ec.inverse()             
sage: Ec_to_cart.display()                                                                          
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

See E.chart? and Ec0.transition_map? for more details.

EDIT:

Another option is not to use Sage's standard spherical coordinates, but link your spherical coordinates directly to the Cartesian ones via transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: E.set_default_chart(Ec)                                                                                          
sage: E.set_default_frame(Ec.frame())                                                                                  
sage: cart = E.cartesian_coordinates()                                                              
sage: Ec_to_cart = Ec.transition_map(cart, (r*cos(theta)*cos(phi), r*sin(theta)*cos(phi), r*sin(phi)))                 
sage: Ec_to_cart.display()                                                                                             
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

To complete the relation to Cartesian coordinates, you have to provide the inverse transition map (it is too involved for Sage to compute it automatically via the method inverse()). This is done by means of set_inverse:

sage: Ec_to_cart.set_inverse(sqrt(x^2 + y^2 + z^2), atan2(y, x), atan(z/sqrt(x^2 + y^2)))                              
Check of the inverse coordinate transformation:
  r == r  *passed*
  theta == arctan2(r*cos(phi)*sin(theta), r*cos(phi)*cos(theta))  **failed**
  phi == arctan(sin(phi)/cos(phi))  **failed**
  x == x  *passed*
  y == y  *passed*
  z == z  *passed*
NB: a failed report can reflect a mere lack of simplification.

You have then:

sage: Ec_to_cart.inverse().display()                                                                                   
r = sqrt(x^2 + y^2 + z^2)
theta = arctan2(y, x)
phi = arctan(z/sqrt(x^2 + y^2))

As a check that everything goes well with your version of spherical coordinates, you can ask Sage to display the Euclidean metric:

sage: E.metric().display()                                                                                             
g = dr*dr + r^2*cos(phi)^2 dtheta*dtheta + r^2 dphi*dphi

EDIT 2: orthonormal frame associated with the customized spherical coordinates

One may introduce the orthonormal frame $(e_r, e_{\theta}, e_{\phi})$ such that $e_r = \frac{\partial}{\partial r}$, $e_\theta = \frac{1}{r\cos\phi} \frac{\partial}{\partial\theta}$, $e_\phi = \frac{1}{r}\frac{\partial}{\partial\phi}$, as follows:

sage: e1 = E.vector_field(1, 0, 0, name='e_r')                                                      
sage: e1.display()                                                                                  
e_r = d/dr
sage: e2 = E.vector_field(0, 1/(r*cos(phi)), 0, name='e_theta')                                     
sage: e2.display()                                                                                  
e_theta = 1/(r*cos(phi)) d/dtheta
sage: e3 = E.vector_field(0, 0, 1/r, name='e_phi')                                                  
sage: e3.display()                                                                                  
e_phi = 1/r d/dphi
sage: e = E.vector_frame('e', (e1, e2, e3))

Then:

sage: for v in e: 
....:     v.display(Ec.frame()) 
....:                                                                                               
e_1 = d/dr
e_2 = 1/(r*cos(phi)) d/dtheta
e_3 = 1/r d/dphi
sage: for v in e: 
....:     v.display(cart.frame()) 
....:                                                                                               
e_1 = cos(phi)*cos(theta) e_x + cos(phi)*sin(theta) e_y + sin(phi) e_z
e_2 = -sin(theta) e_x + cos(theta) e_y
e_3 = -cos(theta)*sin(phi) e_x - sin(phi)*sin(theta) e_y + cos(phi) e_z

The dual coframe is

sage: e.coframe()                                                                                   
Coframe (E^3, (e^1,e^2,e^3))
sage: for f in e.coframe(): 
....:     f.display(Ec.frame()) 
....:                                                                                               
e^1 = dr
e^2 = r*cos(phi) dtheta
e^3 = r dphi

We check that e is an orthonormal frame:

sage: E.metric().display(e)                                                                         
g = e^1*e^1 + e^2*e^2 + e^3*e^3
sage: E.metric()[e,:]                                                                               
[1 0 0]
[0 1 0]
[0 0 1]

and use it as the default vector frame on the Euclidean space E:

sage: E.set_default_frame(e)