2

I am running a simulation and I need to update a plot of a matrix every iteration (or every n iterations for that matter). I am doing the plotting using matplotlib, in particular matshow. I tried replicating the code I saw in other StackOverflow questions but I haven't been successful. Currently the code just produces different windows with the new plots instead of updating the first one. Here's the code so far:

import numpy as np
import random
import math
import matplotlib.pyplot as plt
import matplotlib.animation as anim

#   System variables initialization
N = 50
n_iter = 5
betaJ = 0.40
lattice = np.ones([N, N])
energy = -2*betaJ*N**2
choices = list(range(N))

plt.ion()
fig = plt.figure()

#   Main cycle
for i in range(0, n_iter):
    #   Pick random spin and calculate energy variation caused by flipping it
    x, y = random.choice(choices), random.choice(choices)
    neighbour_spin_sum = lattice[np.mod(x-1, N), y] + lattice[np.mod(x+1, N), y] + lattice[x, np.mod(y+1, N)] + lattice[x, np.mod(y-1, N)]
    delta_energy = 2*betaJ*(neighbour_spin_sum*lattice[x, y])

    #   If energetically favorable, flip spin
    if delta_energy < 0:
        lattice[x, y] = -lattice[x, y] 

    #   Else flip with some probability
    elif random.uniform(0, 1) <= math.exp(-delta_energy):
        lattice[x, y] = -lattice[x, y] 

    plt.matshow(lattice)
    plt.draw()
    plt.pause(0.0001)

Thanks!

3
  • I highly suggest you change n_iter to something more reasonable for this code, else unsuspecting people running this will get 10,000 new windows opened. Commented Mar 3, 2016 at 20:00
  • Oops, you're completely right. Changing it now. Commented Mar 3, 2016 at 20:31
  • Not a solution to your question directly, but you can try other plotting methods that don't require using matshow. imshow might be close to what you're looking for. Commented Mar 3, 2016 at 20:36

1 Answer 1

2

The issue is that every time the plt.matshow() is called matplotlib creates a new plotting axis. To get around this, define the axis and keep reusing it as shown below:

import numpy as np
import random
import math
import matplotlib.pyplot as plt
import matplotlib.animation as anim

#   System variables initialization
N = 50
n_iter = 10000
betaJ = 0.40
lattice = np.ones([N, N])
energy = -2 * betaJ * N ** 2
choices = list(range(N))

plt.ion()
fig = plt.figure()

#   Main cycle
for i in range(0, n_iter):
    #   Pick random spin and calculate energy variation caused by flipping it
    x = random.choice(choices)
    y = random.choice(choices)
    neighbour_spin_sum = lattice[np.mod(x-1, N), y] + lattice[np.mod(x+1, N), y] + lattice[x, np.mod(y+1, N)] + lattice[x, np.mod(y-1, N)]

    delta_energy = 2*betaJ*(neighbour_spin_sum*lattice[x, y])

    #   If energetically favorable, flip spin
    if delta_energy < 0:
        lattice[x, y] = -lattice[x, y] 

    #   Else flip with some probability
    elif random.uniform(0, 1) <= math.exp(-delta_energy):
        lattice[x, y] = -lattice[x, y] 

    ax = fig.add_subplot(111)
    ax.matshow(lattice)
    plt.draw()
    plt.pause(0.0001)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the reply! This seems to only work on python 2, any idea why?
It works for me in python 2.7.11 and 3.4.2 (which is a little out of date) Which version specifically are you looking to use it with?

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.