Last active
December 14, 2022 09:07
-
-
Save MarcSkovMadsen/756fe0cf392a35c3c826194b831ad1a3 to your computer and use it in GitHub Desktop.
Matplotlib interactive extension
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import panel as pn | |
from panel.pane.plot import Matplotlib as _MatplotlibPane | |
import param | |
import numpy as np | |
from matplotlib.figure import Figure | |
from matplotlib import cm | |
from matplotlib.backends.backend_agg import FigureCanvasAgg # not needed for mpl >= 3.1 | |
pn.extension() | |
# Custom implementation of Matplotlib pane for now | |
# Should go back into Panel Matplotlib pane at some stage | |
class MatplotlibInteractive(_MatplotlibPane): | |
_rename = {**_MatplotlibPane._rename, "event": None, "events": None} | |
_priority = -1 | |
event = param.Parameter() | |
events = param.List() | |
def _get_widget(self, fig): | |
import matplotlib | |
old_backend = getattr(matplotlib.backends, "backend", "agg") | |
from ipympl.backend_nbagg import FigureManager, Canvas, is_interactive | |
from matplotlib._pylab_helpers import Gcf | |
matplotlib.use(old_backend) | |
canvas = Canvas(fig) | |
fig.patch.set_alpha(0) | |
manager = FigureManager(canvas, 0) | |
if is_interactive(): | |
fig.canvas.draw_idle() | |
def closer(event): | |
canvas.mpl_disconnect(cid) | |
Gcf.destroy(manager) | |
cid = canvas.mpl_connect("close_event", closer) | |
def handle_event(event): | |
self.event = event | |
for ev in self.events: | |
if not ev == "close_event": | |
fig.canvas.mpl_connect(ev, handle_event) | |
return manager | |
## Matplotlib Interactive Example | |
FONTAWESOME_LINK = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.css" | |
pn.config.css_files.append(FONTAWESOME_LINK) | |
pn.extension(sizing_mode="stretch_width") | |
def get_mpl(): | |
Y, X = np.mgrid[-3:3:100j, -3:3:100j] | |
U = -1 - X ** 2 + Y | |
V = 1 + X - Y ** 2 | |
fig0 = Figure(figsize=(8, 6)) | |
ax0 = fig0.subplots() | |
# FigureCanvasAgg(fig0) # not needed for mpl >= 3.1 | |
strm = ax0.streamplot(X, Y, U, V, color=U, linewidth=2, cmap=cm.autumn) | |
fig0.colorbar(strm.lines) | |
return MatplotlibInteractive( | |
fig0, | |
dpi=144, | |
interactive=True, | |
events=["button_press_event", "button_release_event", "motion_notify_event"], | |
) | |
mpl = get_mpl() | |
pn.template.FastListTemplate( | |
site = "Awesome Panel", title = "Matplotlib with events", | |
main = [pn.Column( | |
mpl, | |
pn.layout.HSpacer(height=700), # Hack because the Matplotlib Pane does not set its "height" correctly | |
mpl.param.event, | |
) | |
] | |
).servable() |
Why there is so much white space above? Is what you mean with "height parameter not working"? Is there a way to eliminate white space? I've tried tight layout options unsuccessfully.
Thanks for the question. Are you referring to white space in the code or the app shown?
referring to white space in the code or the app shown?
The matplotlib figure shows.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This example is developed as a short term solution for enabled interactive Matplotlib applications based on events using Panel.
C.f. Panel Feature Request #2349.
This will give us time to discuss the right api and implementation before we add this to back into Panel.
I will keep a list of things that are "Not working yet" and update it as we go.
Run it via
panel serve matplotlib_interactive.py
.Not working yet
height
parameter not working