0

This will be a pretty basic question but I am a bit stuck on two things.

I have some data stored in a 2D array, let's just call it z. I have two separate 2D arrays, nxp and nyp that hold mapping information for every element in z. nxp and nyp therefore currently hold Cartesian co-ordinates and I want to transform this to polar co-ordinates. Following this, I have defined polar to convert a given (x,y) to (r, theta) as:

import numpy as np
import math

def polar(x, y):
    '''
    Args:
        x (double): x-coordinate.
        y (double): y-coordinate.

    Returns:
        r, theta (in degrees).
    '''
    r = np.hypot(x, y)
    theta = math.degrees(math.atan2(y, x))
    return r, theta

But from this point on I think everything I am doing is a really bad approach to this problem. Ideally I would like to just feed in the Cartesian arrays and get back the polar arrays but this doesn't seem to work with my defined function (which is probably because I've defined input type as double implicitly but I was hoping python would be able to overload here).

r, theta = polar(nxp, nyp)

The traceback is:

.... in polar
theta = math.degrees(math.atan2(y,x))

TypeError: only size-1 arrays can be converted to Python scalars

So I am now implementing transforming everything to a 1D list and iterating to populate r and theta. E.g.

nxp_1D = nxp.ravel()
nyp_1D = nyp.ravel()

for counter, value in enumerate(nxp_1D):
    r, theta = polar(value, nyp_1D[counter])

This exact implementation is faulty as it returns just a single value for r and theta, rather than populating a list of values.

More generally though I really don't like this approach for a few reasons. It looks to be a very heavy-handed solution to this problem. On top of this, I might want to do some contourf plots later and this would necessitate converting r and theta back to their original array shapes.

Is there a much easier and more efficient way for me to create the 2D arrays r and theta? Is it possible to create them either by changing my polar function definition or maybe by using list comprehension?

Thanks for any responses.

  • 1
    `math.atan2` doesn't seem right here. You're using numpy. – user202729 Sep 22 '20 at 04:17
  • 1
    Why don't you just use the accepted answer there? That one uses numpy, and you're using numpy too. – user202729 Sep 22 '20 at 04:18
  • 1
    Try using `np.arctan2` and `np.degrees` for a fully vectorized implementation. – Igor Raush Sep 22 '20 at 04:19
  • 1
    Possible duplicate: [1](https://stackoverflow.com/questions/36680402/typeerror-only-length-1-arrays-can-be-converted-to-python-scalars-while-plot-sh) [2](https://stackoverflow.com/questions/63515866/only-size-1-arrays-can-be-converted-to-python-scalars) [3](https://stackoverflow.com/questions/21687581/typeerror-only-length-1-arrays-can-be-converted-to-python-scalars-while-trying) [4](https://stackoverflow.com/questions/45785946/python-typeerror-only-length-1-arrays-can-be-converted-to-python-scalars) -- all because the OP try to pass a numpy array into math.* functions. – user202729 Sep 22 '20 at 04:24
  • Just as a follow up question are there ever any particular circumstances in which to use `math` over `numpy`? [This](https://stackoverflow.com/questions/41648058/what-is-the-difference-between-import-numpy-and-import-math) suggests that you should just always use `numpy` but then I don't see why `math` even exists if `numpy` basically always outperforms it. – imwellhowareyou Sep 22 '20 at 04:30
  • "to keep your program light, you should stick with math library." -- the second answer there. – user202729 Sep 22 '20 at 04:32

1 Answers1

1

Yep, OK, so that was a very easy fix. Thank you to @user202729 and @Igor Raush. It was as simple as:

def polar(x, y)
    r = np.hypot(x, y)
    theta = np.arctan2(y, x)
    return r, theta

.....
r, theta = polar(nxp, nyp)

Sorry for how daft that question was but thanks for your responses.