문제

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