سؤال

I want to plot an approximation of the number "pi" which is generated by a function of two uniformly distributed random variables. The goal is to show that with a higher sample draw the function value approximates "pi".

Here is my function for pi:

def pi(n):
    x  = rnd.uniform(low  = -1,  high = 1, size = n) #n = size of draw
    y  = rnd.uniform(low  = -1,  high = 1, size = n)
    a  = x**2 + y**2 <= 1      #1 if rand. draw is inside the unit cirlce, else 0
    ac = np.count_nonzero(a)   #count 1's
    af = np.float(ac)          #create float for precision
    pi = (af/n)*4              #compute p dependent on size of draw
    return  pi

My problem:

I want to create a lineplot that plots the values from pi() dependent on n.

My fist attempt was:

def pipl(n):
    for i in np.arange(1,n):
        plt.plot(np.arange(1,n), pi(i))
        print plt.show()

pipl(100)

which returns:

ValueError: x and y must have same first dimension

My seocond guess was to start an iterator:

def y(n):
    n = np.arange(1,n)
    for i in n:
        y = pi(i)
        print y

 y(1000)

which results in:

3.13165829146
3.16064257028
3.06519558676
3.19839679359
3.13913913914

so the algorithm isn't far off, however i need the output as a data type which matplotlib can read.

I read:

http://docs.scipy.org/doc/numpy/reference/routines.array-creation.html#routines-array-creation

and tried tom implement the function like:

...
y = np.array(pi(i))
...

or

...
y = pi(i)
y = np.array(y)
...

and all the other functions that are available from the website. However, I can't seem to get my iterated y values into one that matplotlib can read.

I am fairly new to python so please be considerate with my simple request. I am really stuck here and can't seem to solve this issue by myself.

Your help is really appreciated.

هل كانت مفيدة؟

المحلول

You can try with this

def pipl(n):
    plt.plot(np.arange(1,n), [pi(i) for i in np.arange(1,n)])
    print plt.show()

pipl(100)

that give me this plot

enter image description here

نصائح أخرى

If you want to stay with your iterable approach you can use Numpy's fromiter() to collect the results to an array. Like:

def pipl(n):
    for i in np.arange(1,n):
        yield pi(i)

n = 100

plt.plot(np.arange(1,n), np.fromiter(pipl(n), dtype='f32'))

But i think Numpy's vectorize would be even better in this case, it makes the resulting code much more readable (to me). With this approach you dont need the pipl function anymore.

# vectorize the function pi
pi_vec = np.vectorize(pi)

# define all n's 
n = np.arange(1,101)

# and plot
plt.plot(n, pi_vec(n))

enter image description here

A little side note, naming a function pi which does not return a true pi seems kinda tricky to me.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top