0

I'm working on a project and I got a piece of code to work in a for loop just fine, as it works in a for loop, it should work in a func for making an animation of the actual array instead of just as the total value of the sum of the numbers in the array which was the final result of the original for loop. This may be a case of still not totally understanding how matplotlibs plotting works so I was hoping someone could take a look at it for me and see what I'm doing wrong.

Here's my code as it is right now with the initializing variables. I've tried using both matshow and data_set and neither seem to do much for me. I can see my initial array graphed but I can't get an animation. I'd also like to save the animation as an mp4 afterwards and when I tried doing that I got errors with the mp4 file type.

EDIT: For clarification, the main problem I'm having is with FuncAnimation and getting the animation to show. I'm not having trouble with the stuff inside the function to be animated as a I tested that separately, except for the parts related to animation.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as anim
import matplotlib as mpl
import random as rand

#defining our function to multiply adjacent numbers of a given 2D array and add them
def adjacent_multiply(array):
    shape = array.shape
    
    left_adjacent = array[ : , 0:(shape[1]-1)]
    left_adjacent = np.insert(left_adjacent, [0], 0, axis = 1)
    left_product = left_adjacent * array
    
    down_adjacent = array[0:(shape[1]-1), :]
    down_adjacent = np.insert(down_adjacent, [0], 0, axis = 0)
    down_product = down_adjacent * array
    
    return sum(sum(left_product)) + sum(sum(down_product))

n = 20
J = 1
T = 1
k_b = 1
beta = 1/(k_b * T)
c = mpl.colors.ListedColormap(['black', 'gray'])
normal = mpl.colors.Normalize(vmin=-1,vmax=1)
arr = np.random.choice([-1, 1], size = (n,n))
m = 1000

#setting up the figure
fig = plt.figure()
im = plt.matshow(arr, cmap = c, norm = normal)

#function animation function
def func(i):
    stepstart = -J * adjacent_multiply(arr)
    
    #making a random acceptable move by flipping one value
    i = np.random.choice(n, size = 1)
    j = np.random.choice(n, size = 1)
    arr[i, j] = arr[i, j] * -1
    
    stepend = -J * adjacent_multiply(arr)
    change = stepend - stepstart
    
    #conditional for rejecting a move
    if rand.random() > np.exp(-beta*change):
        arr[i, j] = arr[i, j] * -1
    
    im.set_data(arr)
    
    return [im]

animation = anim.FuncAnimation(fig, func, frames = 1000, blit = True)
plt.show()
6
  • Could you make this into a reproducible example so people can run it? stackoverflow.com/help/minimal-reproducible-example Commented May 11, 2024 at 21:27
  • Here I've updated it now, sorry about that. Commented May 12, 2024 at 16:57
  • Your code works for me, although I got an extra blank figure. I got rid of the extra figure by passing fignum=fig.number in the call to matshow. Adding animation.save('test.mp4') before the plt.show() line also works for me. Commented May 13, 2024 at 19:54
  • What backend are you using? You can use plt.get_backend() to find out if you're not sure. Commented May 13, 2024 at 19:56
  • 1
    Update, added %matplotlib qt to the beginning of the code and it works fine now. Issue is resolved. Commented May 13, 2024 at 22:13

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.