0

I'm trying to create an interactive 4-channel stripchart in my PyQt5 GUI and I'm using matplotlib to do so. I already have the matplotlib plot embedded into the GUI as a widget, now I'm trying to make use of the matplotlib.animate module in order for the plots to update. I keep getting a KeyError when referring to the lines I've currently added to the axes. Besides the updating of the plot everything functions as expected so far, so I'm only including the code I believe is relevant.

class StripchartBuilder(QtWidgets.QDialog, StripchartDialog.Ui_Dialog):
    def __init__(self, ..., parent=None)
        self.fig = Figure()
        self.ax1 = self.fig.add_subplot(111)
        self.addfigure()
        self.channels = {'CH 1': {'signal': 'None',
                                  'scale': 'x1',
                                  'cursor': False,
                                  'data': [0],
                                  'line': Line2D(self.tdata, [0], color='r')
                                  },
                         ...
                          }
        self.prevsig{'CH 1': 'None',...}

    def addfigure(self):
        self.canvas = FigureCanvas(self.fig)
        self.canvas.draw()

        self.toolbar = NavigationToolbar(self.canvas,
                                         self.mplwindow, coordinates=True)
        self.mplvl.addWidget(self.toolbar)
        self.mplvl.addWidget(self.canvas)

    def update(self, i):
        print(self.ax1.lines)
        return [self.channels['CH 1']['line']

    def addline(self, chan):
        self.ax1.add_line(self.channels[chan]['line'])
        self.ani = animation.FuncAnimation(self.fig,
                                           self.update,
                                           interval=10,
                                           blit=True)

Screencap of the GUI design.

Basically the idea is that I have 4 channels on which to monitor things. I have a dictionary, channels each key corresponding to one channel. The line parameter for each stores a Line2D object. When I turn the spinner under the Data Item label to something besides 'None' I add the associated line to the plot. Up to this point everything seems to work fine.I can add and remove the lines as I like, the problem is I can't get the animate.FuncAnimation to work. I've basically stopped trying to do anything inside the update method, because I simply can't get it to run at all.

When the addline method is called by setting one of those spinners, the program almost immediately throws a KeyError on, I assume, what I'm returning from the update method. I added the two prints in update in an attempt to try and debug what's going on. When I print the channels dictionary and self.ax1.lines they both give me the same address for the object, but the KeyError I'm encountering is trying to access something else, and it appears to be trying to do something with an entirely different type of object.

For example:

print(self.ax1.lines) will return:

[<matplotlib.lines.Line2D object at 0x0000000006F0DD68>]

The KeyError I receive is:

KeyError: <matplotlib.axes._subplots.AxesSubplot object at   0x0000000006D44BE0>

I'm obviously doing something wrong, but I'm not sure exactly what that is. What am I supposed to be returning in my update method? Is that even what the problem is?

Mikhail
  • 33
  • 4
  • There is a closing bracket `]` missing in the update function. Appart from that, I'm not sure what exactly you are trying to animate here. Also, if two lines are added, you have two FuncAnimations running? How should that work? – ImportanceOfBeingErnest Nov 17 '16 at 22:54
  • I actually ended up trashing this idea after figuring out that matplotlib wouldn't do too well with real-time updates, it's kind of slow. I ended up using the PyQtGraph module, which worked swimmingly once I figured out how to use it. – Mikhail Dec 05 '16 at 13:44
  • PyQtGraph is indeed much faster, as can be seen e.g. [in this comparison](http://stackoverflow.com/a/40139416/4124317). But speed has not been mentioned as a requirement in the question at all. – ImportanceOfBeingErnest Dec 05 '16 at 13:53
  • After beating my head against a wall several times, and figuring out that matplotlib is not friendly with live updates, I decided that it wasn't going to work for my purposes. I ended up using the pyqtgraph module which works really well. I also looked into using VisPy, but it seems like they're a little bit lacking as of yet, once that project matures more I'd love to take a shot at using it. – Mikhail Dec 05 '16 at 13:48

0 Answers0