重组数据并更新 imshow 图

Rebin data and update imshow plot

我有一个大数据集,我希望能够 "zoom" 上。

我真正想要的是根据选择对数据进行重新分类,然后更新图中的数据。因此图表将显示不同的限制但保持相同的分辨率。目前 imshow 没有更新。一定有什么我遗漏或不明白的东西,我们将不胜感激。

随机数据工作示例:

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()

您似乎错过了 update_data 重绘直方图中 y 值的限制。高指数和低指数也是错的。下面看起来更有希望,

    Z, xedges, yedges = np.histogram2d(x[high_index:low_index],y[high_index:low_index], bins=150)

(虽然我不确定这是否正是您想要的)

编辑:以下显示缩放和重绘。

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Rectangle

class Annotate(object):
  def __init__(self,x,y):
      self.figure = plt.gcf()
      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.is_pressed = False
      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.is_pressed is False:
          return
      self.x1 = event.xdata
      self.y1 = event.ydata
      #if type(self.x1) is float and type(self.y1) is float:
      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(5000)
y = np.random.randint(0,500, size=5000)

Z, xedges, yedges = np.histogram2d(x, y, bins=150, normed=True)

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[high_index:low_index],y[high_index:low_index], bins=150, normed=True)

    selection.ax.figure.clf(keep_observers=True)
    selection.ax = selection.ax.figure.add_subplot(111)
    selection.im=plt.imshow(Z, interpolation='none', extent=[xmin, xmax, ymin, ymax])
    plt.colorbar(selection.im)


selection = Annotate(x,y)

selection.im=plt.imshow(Z, interpolation='none', extent=[y.min(), y.max(), y.min(), y.max()])
plt.colorbar(selection.im)

plt.show()