Skip to content

Instantly share code, notes, and snippets.

@thomasaarholt
Last active November 20, 2020 12:26
Show Gist options
  • Save thomasaarholt/4bbde6e90255ea00dbca68d4bedb8753 to your computer and use it in GitHub Desktop.
Save thomasaarholt/4bbde6e90255ea00dbca68d4bedb8753 to your computer and use it in GitHub Desktop.
Matplotlib Navigator and Signal plot with draggable marker
%matplotlib qt
import numpy as np
import matplotlib.pyplot as plt
fig, ax1 = plt.subplots(ncols=1)
fig2, ax2 = plt.subplots(ncols=1)
imdata = np.random.random((20,20))
im = ax1.imshow(imdata, animated=True)
(ln,) = ax2.plot(np.random.random(200), animated=True)
data = np.random.random((np.prod(imdata.shape), 200))
def position(x, y):
x, y = np.round([x,y]) - 0.5
return (x, y)
class box:
def __init__(self, ax1=None, ax2=None, im=None, ln=None, data=None):
self.ax1 = ax1
self.ax2 = ax2
self.ln = ln # remove
self.canvas1 = ax1.figure.canvas
self.canvas2 = ax2.figure.canvas
self.fig = ax1.figure
self.fig2 = ax2.figure
self.canvas1.draw()
self.canvas2.draw()
self.indices = (0,0)
self.draggable = False
self.init()
self.c1 = self.canvas1.mpl_connect("button_press_event", self.click)
self.c2 = self.canvas1.mpl_connect("button_release_event", self.release)
self.c3 = self.canvas1.mpl_connect("motion_notify_event", self.drag)
self.cid = self.canvas1.mpl_connect("draw_event", self.on_draw)
self.cid2 = self.canvas2.mpl_connect("draw_event", self.on_draw)
def init(self):
self.background1 = self.canvas1.copy_from_bbox(self.fig.bbox)
self.background2 = self.canvas1.copy_from_bbox(self.fig.bbox)
self.marker = plt.Rectangle(position(0,0), 1,1, fill=True, animated=True)
self.ax1.add_artist(self.marker)
def click(self, event):
if event.inaxes == self.ax1:
self.draggable = True
ex,ey = event.xdata, event.ydata
x,y = position(ex, ey)
self.indices = (x,y)
self.marker.set_xy(self.indices)
self.ln.set_ydata(data[np.sum(self.indices, dtype=int)])
self.blit()
def release(self, event):
self.draggable = False
def drag(self, event):
if event.inaxes == self.ax1:
if self.draggable:
ex, ey = event.xdata, event.ydata
x,y = position(ex, ey)
oldxy = self.marker.get_xy()
if not (x,y) == oldxy:
self.indices = (x,y)
self.marker.set_xy(self.indices)
self.ln.set_ydata(data[np.sum(self.indices, dtype=int)])
self.blit()
def blit(self):
self.canvas1.restore_region(self.background1)
self.canvas2.restore_region(self.background2)
self.ax1.draw_artist(self.marker)
self.ax2.draw_artist(self.ln)
self.canvas1.blit(self.fig.bbox)
self.canvas2.blit(self.fig2.bbox)
def on_draw(self, event):
self.canvas1.mpl_disconnect(self.cid)
self.canvas2.mpl_disconnect(self.cid2)
self.marker.set_visible(False)
self.canvas1.draw()
self.canvas2.draw()
self.background1 = self.canvas1.copy_from_bbox(self.canvas1.figure.bbox)
self.background2 = self.canvas2.copy_from_bbox(self.canvas2.figure.bbox)
self.marker.set_visible(True)
self.cid = self.canvas1.mpl_connect("draw_event", self.on_draw)
self.cid2 = self.canvas2.mpl_connect("draw_event", self.on_draw)
b = box(ax1, ax2, im, ln, data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment