In the backend file backend_wx.py
you can see that matplotlib draws directly onto the window, and over the button you created before. What you have to do is to replace the draw
method with one that triggers a redraw for the button after it drew the graph:
fig = figure()
but = Button(fig.canvas, label="button")
original_draw = fig.canvas.draw
def draw(gc=None):
original_draw(gc)
but.SetLabel(but.GetLabel())
fig.canvas.draw = draw
plot([1],[1])
I use but.SetLabel(but.GetLabel())
to force a redraw of the button. Sending an apropriate paint event using wx.PostEvent
should work as well. If you have more than one control and don't want to draw over all of them, since resizing solves the problem, you could use SendSizeEvent()
to trigger a redraw. You'll have to add some mechanism to prevent an infinite loop then, because the size event handler calls draw
again.
The best solution is probably to write an own matplotlib backend, one which does not draw into the main window but into a canvas child, such that the GUI toolkit can handle the drawing order. But that's also the most involved solution. The documentation has some information on that topic, and you might also find the already mentioned backend_wx.py
helpful.
By the way: If the button does not need to be on top of the canvas, you can also add it to the toolbar through gcf().canvas.toolbar
.