使用 set_data() 更新一行后,Matplotlib 的“重置原始视图”按钮会缩放到先前数据的限制

问题描述

使用 Python 3.8、Matplotlib 3.3.2,在 GTK3 GUI 中嵌入图形画布。

问题陈述:

我有一个带有 GTK3 GUI 的程序,下拉菜单中有数百个变量,每个变量都有要绘制的 x/y 数据。我正在尝试在我的图下方添加一个 NavigationToolbar,以便用户可以放大和缩小。这适用于初始图形,但是当用户选择不同的变量,并且使用 axis.lines[0].set_data(x,y) 更新行的数据时,工具栏上的 重置原始视图 按钮重置到第一个数据集,而不是新数据集(假设用户放大了第一个数据集)。

有没有办法告诉 NavigationToolbar 图形中的绘制数据已更改,因此重置视图可以正常工作?

示例代码

import gi
gi.require_version('Gtk','3.0')
from gi.repository import Gtk

from matplotlib.backends.backend_gtk3agg import figureCanvasGTK3Agg as figureCanvas
from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar
import matplotlib.pyplot as plt
import numpy as np


class PlotDemo(Gtk.Window):
   def __init__(self):
      Gtk.Window.__init__(self,title="Navigation Demo")
      self.set_border_width(4)

      self.set_default_size(850,650)

      self.Box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
      self.add(self.Box)

      buttonBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
      self.Box.add(buttonBox)

      sineButton = Gtk.Button(label='SIN')
      sineButton.connect('clicked',self.plotSin)
      buttonBox.add(sineButton)

      cosineButton = Gtk.Button(label='COS')
      cosineButton.connect('clicked',self.plotCos)
      buttonBox.add(cosineButton)

      self.figure,self.axis = plt.subplots()

      self.time = np.arange(0.0,3.0,0.01)
      self.sin = 100*np.sin(2*np.pi*self.time)
      self.cos = np.cos(2*np.pi*self.time)

      self.axis.plot(self.time,self.sin)
      self.axis.set_xlim(0,3)

      self.canvas = figureCanvas(self.figure)
      self.canvas.set_size_request(800,600)
      self.canvas.draw()

      self.navigation = NavigationToolbar(self.canvas,self)

      self.Box.add(self.canvas)
      self.Box.add(self.navigation)

      self.show_all()


   def plotSin(self,_unused_widget):
      self.update(self.time,self.sin)


   def plotCos(self,self.cos)


   def update(self,x,y):
      self.axis.lines[0].set_data(x,y)
      self.autoScaleY()


   def autoScaleY(self):
      self.axis.relim()
      self.axis.autoscale(axis='y')
      self.canvas.draw()


win = PlotDemo()
win.connect("destroy",Gtk.main_quit)
win.show_all()
Gtk.main()

重现问题的步骤:

1. Run script. Plotted SIN data should be visible.
2. Click "Zoom to rectangle" button on toolbar
3. Zoom in on the SIN plot
4. Click "Reset original view" button on toolbar
5. Click "COS" button at top
6. Initial view should be correct,since I auto-scale the Y-Axis
7. Zoom (optional),and then click "Reset original view" button again

问题:第 7 步缩小到原来的 Y 轴范围 [-100,100]

预期行为:将视图重置为新数据集的适当限制 [-1,1]

解决方法

我想我发帖有点太快了。稍微挖掘了一下,我找到了一个解决方案。

NavigationToolbar2GTK3 继承自 NavigationToolbar2,它有一个 update() 方法可以清除导航堆栈,这就是 home() 方法所指的内容。

在示例代码中,将我的 update() 方法更改为此解决了它:

def update(self,x,y):
   self.axis.lines[0].set_data(x,y)
   self.autoScaleY()
   self.navigation.update()