Mpl_iteractions with gui outside of jupyter notebooks

Is there a way to use mpl_iteractions with a gui (e.g. pysimplegui, tkinter, etc) outside of jupyter notebooks? I can render the graphs in tkinter, but I cannot interact with them. I have tried using with plt.ion() .

Hi David,

Can you post a code snippet of what is not working for you? Everything should work in any interactive backend, though I have only tested using Qt5Agg.

In particular can you try putting this script into a file and running it:

import matplotlib.pyplot as plt
import numpy as np
from mpl_interactions import interactive_plot, interactive_plot_factory

x = np.linspace(0,np.pi,100)
tau = np.linspace(1,10, 100)
beta = np.linspace(.001,1)
def f(x, tau, beta):
    return np.sin(x*tau)*x**beta
fig, ax, sliders = interactive_plot(f, x=x, tau = tau, beta = beta, slider_format_string={'beta': '%1.3e'})
plt.legend()
plt.show()

Script from: https://mpl-interactions.readthedocs.io/en/latest/examples/mpl-sliders.html

Oh wait, I think I may have misunderstood. What I know should work is using mpl_interactions from a script or from an (i)python repl. I’ve never tried embedding inside of a custom made gui. Are you trying to make a gui and have this plot as one part of it? I think a good first debugging step would be to see if you can get the official matplotlib example of interactions to work in your GUI framework: https://matplotlib.org/3.1.1/gallery/widgets/slider_demo.html

I just tried combining two matplotlib examples to get interactive sliders in a tkinter gui to no avail. (n.b. no mpl-interactions, pure matplotlib)

In particular I combined:
https://matplotlib.org/3.1.1/gallery/widgets/slider_demo.html
and
https://matplotlib.org/3.1.0/gallery/user_interfaces/embedding_in_tk_sgskip.html

the code is all in this gist:

When I run it I get this. The slider doesn’t seem to work, but I can still pan around so some sort of interaction works.

I’m not really sure what’s going on here, except that I clearly don’t fully understand how to embed matplotlib into a gui. Maybe @story645 knows what to look at here?

Ok so if I take the canvas object returned by FigureCanvasTkAgg and use mpl_connect on that:

def mouse_move(event):
    print(event)
canvas.mpl_connect("motion_notify_event", mouse_move)

then the events get picked up. However, if I do the same with fig.canvas no events are detected because those are different canvases I guess?

And my example with the matplotlib slider doesn’t work because the sliders only access fig.canvas to connect events:


This may be a bug with Matplotlib? I would have expected fig.canvas.mpl_connect to always work regardless of backend or whether mpl is embedded in a gui.

@drfeinberg are you trying to embed heatmap_slicer into a larger gui? If you are then I think if you go and change these line: https://github.com/ianhi/mpl-interactions/blob/e7f9977168f811f3a5189eb7c7312ea6d1822f99/mpl_interactions/generic.py#L182-L184 to use the Tk canvas rather than the figure canvas you may be able to get it to work. If makes your life easier feel free to copy the heatmap slicer code and make whatever modifications you’d like. If you do do that then I’d appreciate a comment pointing back to my github repo - and of course PRs for improvement are very welcome :slight_smile:

@ianhi The issue is that when you create a figure we have a default FigureCanvasAgg attached to it (so figure.Figure().savefig() works ). This a a relatively recent change to behavior, Figure objects used to init with fig.canvas is None . In your example what is happening is that you are creating a figure, it has a canavs, you are setting up the interactions on that canvas, you are then throwing that canvas away (it might even get GC’d), replacing it with a now FigureCanvasTk instance (which you then pack into your GUI). The new canvas gets the mouse events, shrugs it shoulders and drops them on the floor because you did not tell that canvas you wanted them routed out to your slider.


@drfeinberg I agree with @ianhi, we need a bit more detail to try and answer your question.

oooooh thank you @tacaswell

I suspect @drfeinberg was trying to embed mpl_interactions.heatmap_slicer into a gui framework for some sort of neat sound analysis thing. But this doesn’t work because heatmap slicer always creates a new figure and associated axes using subplots so it can control the layout:

This is in part because I didn’t know figure.subplots existed. So I think I see the way forwards to fixing this

For completeness:

I just fixed this in https://github.com/ianhi/mpl-interactions/pull/108 however as part of my new attempt at healthy living :open_mouth: I’m gonna leave my computer alone now. But this should be on pypi sometime tomorrow (plus scatter plots and imshow!)