1

I'm trying to make a GUI for the game of Tic Tac Toe using Matplotlib. So far, I've made an array of buttons which change their labels to "X" when clicked:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button

def callback(event, button):
    print button
    button.label.set_text("X")

fig, axarr = plt.subplots(3,3, figsize=(6,6))

buttons = [[None for _ in range(3)] for _ in range(3)]
for i in range(3):
    for j in range(3):
        buttons[i][j] = Button(ax=axarr[i][j], label="")
        buttons[i][j].on_clicked(lambda event, i=i, j=j: callback(event, buttons[i][j]))
        axarr[i][j].set_aspect('equal')

fig.tight_layout(h_pad=0, w_pad=0)

plt.show(block=False)

This produces a plot like this:

enter image description here

where I have already clicked all the buttons except one. What I notice when using this GUI, however, is that the new label only becomes visible after I move my mouse off the button, whereas I would like the change to happen immediately. Any ideas how to make this happen?

Kurt Peek
  • 52,165
  • 91
  • 301
  • 526

1 Answers1

1

You just need to add a call to draw_idle which asks the GUI to repaint the window (which in turn re-draws the figure) the next time it is convenient.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button

def callback(event, button):
    print(button)
    button.label.set_text("X")
    if event.inaxes is not None:
        event.inaxes.figure.canvas.draw_idle()

fig, axarr = plt.subplots(3,3, figsize=(6,6))

buttons = [[None for _ in range(3)] for _ in range(3)]
for i in range(3):
    for j in range(3):
        buttons[i][j] = Button(ax=axarr[i][j], label="")
        buttons[i][j].on_clicked(lambda event, i=i, j=j: callback(event, buttons[i][j]))
        axarr[i][j].set_aspect('equal')

fig.tight_layout(h_pad=0, w_pad=0)

plt.show(block=False)
tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • Excellent! For reference, here is the documentation on `draw_idle`: http://matplotlib.org/api/backend_bases_api.html#matplotlib.backend_bases.FigureCanvasBase.draw_idle. – Kurt Peek Aug 11 '16 at 09:03