2

I have encountered a strange problem: when I store a huge amount of data points from a nonlinear equation to 3 arrays (x, y ,and z) and then tried to plot them in a 2D graph (theta-phi plot, hence its 2D).

I tried to eliminate points needed to be plotted by sampling points from every 20 data points, since the z-data is approximately periodic. I picked those points with z value just above zero to make sure I picked one point for every period.

The problem arises when I tried to do the above. I got only a very limited number of points on the graph, approximately 152 points, regardless of how I changed my initial number of data points (as long as it surpassed a certain number of course). graph

I suspect that it might be some command I use wrongly or the capacity of array is smaller then I expected (seems unlikely), could anyone help me find out where is the problem?

def drawstaticplot(m,n, d_n, n_o):
    counter=0
    for i in range(0,m):
        n=vector.rungekutta1(n, d_n)
        d_n=vector.rungekutta2(n, d_n, i)
        x1 = n[0]    
        y1 = n[1]
        z1 = n[2]
        if i%20==0:
            xarray.append(x1)
            yarray.append(y1)
            zarray.append(z1)
    for j in range(0,(m/20)-20):
        if (((zarray[j]-n_o)>0) and ((zarray[j+1]-n_o)<0)):
           counter= counter +1
           print zarray[j]-n_o,counter
           plotthetaphi(xarray[j],yarray[j],zarray[j])

def plotthetaphi(x,y,z):
    phi= math.acos(z/math.sqrt(x**2+y**2+z**2))
    theta = math.acos(x/math.sqrt(x**2 + y**2))
    plot(theta, phi,'.',color='red')

Besides, I tried to apply the code in the following SO question to my code, I want a very similar result except that my data points are not randomly generated.

Community
  • 1
  • 1
  • Hmm. Your indentation looks weird to me -- it should be four spaces everywhere, but look at how far over your `if (((zarray[j]` line is. Run your program with `-tt`, e.g. `python -tt yourprogramname.py` to rule out tab/space errors. I'm also not sure I understand what your `j` loop is doing. – DSM Sep 17 '12 at 15:02
  • i-loop creates 3 arrays, sampling out one point for every 20 points, and putting it into arrays. j-loop considers only those picked out points, hence its size is "m/20". I want pick out a point for every period of z, so I choose those z data that's just above zero in the circumstance that z data is going from positive to negative value. – Yi-Shiuan Huang Sep 17 '12 at 15:51
  • You are having aliasing issues. Do the loops on the other order and I bet you would get a lot more points. Also look into using the numpy built-ins. – tacaswell Sep 17 '12 at 19:12
  • @DSM: You're right, I was not thinking clearly. The j-loop is not directly affected by the i-loop, I don't need to put it so far. – Yi-Shiuan Huang Sep 18 '12 at 03:16

2 Answers2

2

Shiuan,

I am still investigating your problem, how ever a few notes:

Instead of looping and appending to an array you could do:

select every nth element:

# inside IPython console:
[2]: a=np.arange(0,10)

In [3]: a[::2] # here we select every 2nd element.
Out[3]: array([0, 2, 4, 6, 8])

so instead of calcultating runga-kutta on all elements of m:

new_m = m[::20] # select every element of m.

now call your function like this:

def drawstaticplot(new_m,n, d_n, n_o):
    n=vector.rungekutta1(n, d_n)
    d_n=vector.rungekutta2(n, d_n, i)
    x1 = n[0]    
    y1 = n[1]
    z1 = n[2]
    xarray.append(x1)
    yarray.append(y1)
    zarray.append(z1)
    ...

about appending, and iterating over large data sets:

append in general is slow, because it copies the whole array and then stacks the new element. Instead, you already know the size of n, so you could do:

def drawstaticplot(new_m,n, d_n, n_o):
    # create the storage based on n,
    # notice i assumed that rungekutta, returns n the size of new_m, 
    # but you can change it.
    x,y,z = np.zeros(n.shape[0]),np.zeros(n.shape[0]), np.zeros(n.shape[0])

for idx, itme in enumerate(new_m): # notice the function enumerate, make it your friend!
    n=vector.rungekutta1(n, d_n)
    d_n=vector.rungekutta2(n, d_n, ite,)
    x1 = n[0]    
    y1 = n[1]
    z1 = n[2]
    #if i%20==0: # we don't need to check for the 20th element, m is already filtered...
    xarray[idx] = n[0]
    yarray[idx] = n[1]
    zarray[idx] = n[2]
    # is the second loop necessary?
    if (((zarray[idx]-n_o)>0) and ((zarray[j+1]-n_o)<0)): 
       print zarray[idx]-n_o,counter
       plotthetaphi(xarray[idx],yarray[idx],zarray[idx])

    
Community
  • 1
  • 1
oz123
  • 27,559
  • 27
  • 125
  • 187
  • I'm not sure whether this helps, but I'll put my runnable full code here.:p [link](http://ideone.com/8Uccg) The idea is to draw a small spinning top animation and try to analyze its movement. Thanks for providing that useful trick of selecting Nth number, but all my n's and d_n's stands for the spinning top's position and velocity vector. At each step, its generated by the last ones, so I'm afraid I still have to calculate the full series. – Yi-Shiuan Huang Sep 19 '12 at 01:25
  • @Yi-ShiuanHuang, sure it helps, it spares a lot of guessing. – oz123 Sep 19 '12 at 06:45
  • Thanks for your help, I'm still new to programming. I must have already made a lot of noob mistakes.:p And some of the codes borrowed from other places, hence it's kind of messy to some extent. – Yi-Shiuan Huang Sep 19 '12 at 13:38
0

You can use the approach suggested here: Efficiently create a density plot for high-density regions, points for sparse regions e.g. histogram where you have too many points and points where the density is low. Or also you can use rasterized flag for matplotlib, which speeds up matplotlib.

Community
  • 1
  • 1
sega_sai
  • 8,328
  • 1
  • 29
  • 38