I have a large data set I want to be able to "zoom" in on.
What I really want is for the data to be rebinned based on the selection and then update the data in the graph. So the graph will show different limits but maintain the same resolution. Currently the imshow isn't getting updated. There must be something I'm missing or don't understand any insight would be appreciated.
Random data working example:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Rectangle
class Annotate(object):
def __init__(self,x,y):
self.ax = plt.gca()
self.x = x
self.y = y
self.rect = Rectangle((0,0), 0, 0, facecolor='None', edgecolor='red')
self.im = plt.imshow(np.zeros((150,150)))
self.x0 = None
self.y0 = None
self.x1 = None
self.y1 = None
self.ax.add_patch(self.rect)
self.ax.figure.canvas.mpl_connect('button_press_event', self.on_press)
self.ax.figure.canvas.mpl_connect('button_release_event', self.on_release)
self.ax.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)
def on_press(self, event):
print ('press')
self.is_pressed = True
self.x0 = event.xdata
self.y0 = event.ydata
self.x1 = event.xdata
self.y1 = event.ydata
self.rect.set_width(self.x1 - self.x0)
self.rect.set_height(self.y1 - self.y0)
self.rect.set_xy((self.x0, self.y0))
#self.rect.set_linestyle('dashed')
self.ax.figure.canvas.draw()
def on_motion(self,event):
if self.on_press is True:
return
self.x1 = event.xdata
self.y1 = event.ydata
self.rect.set_width(self.x1 - self.x0)
self.rect.set_height(self.y1 - self.y0)
self.rect.set_xy((self.x0, self.y0))
#self.rect.set_linestyle('dashed')
if self.is_pressed == True:
self.ax.figure.canvas.draw()
def on_release(self, event):
print ('release')
self.is_pressed= False
self.x1 = event.xdata
self.y1 = event.ydata
self.rect.set_width(self.x1 - self.x0)
self.rect.set_height(self.y1 - self.y0)
self.rect.set_xy((self.x0, self.y0))
self.rect.set_linestyle('solid')
update_data(self)
#self.ax.set_ylim( min(self.y0, self.y1), max(self.y0, self.y1))
#self.ax.set_xlim( min(self.x0, self.x1), max(self.x0, self.x1))
self.ax.figure.canvas.draw()
print (self.x0,self.x1,self.y0,self.y1)
return [self.x0,self.x1,self.y0,self.y1]
#x = np.random.randint(0,500, size=10000)
x= np.arange(10000)
y = np.random.randint(0,500, size=10000)
Z, xedges, yedges = np.histogram2d(x,y, bins=150)
def update_data(selection):
ymin= min(selection.y0, selection.y1)
ymax= max(selection.y0, selection.y1)
xmin= min(selection.x0, selection.x1)
xmax= max(selection.x0, selection.x1)
low_index = np.argmax(selection.x>xmin)
high_index = np.argmax(selection.y>xmax)
Z, xedges, yedges = np.histogram2d(x[low_index:high_index],y, bins=150)
selection.im.set_data(Z)
selection.im.set_extent([xmin,xmax,ymin,ymax])
plt.draw()
selection = Annotate(x,y)
selection.im=plt.imshow(Z, interpolation='none', extent=[0,500,0,500])
plt.colorbar()
plt.show()
You seem to be missing the limits on the
y
value in the histogram redraw inupdate_data
. The high index and low index are also the wrong way around. The following looks more promising,(although I'm not sure it's exactly what you want)
EDIT: The following appears to zoom and redraw.