Adding an item in matplotlib´s toolbar

后端 未结 2 1236
醉梦人生
醉梦人生 2021-01-25 01:21

I created a matplotlib´s figure in a QMainWindow, using PyQt and I am trying to add a button to the matplotlib´s toolbar in my code. This is the NavigationToo

2条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-25 02:01

    Based on this related SO answer, I wanted a way that doesn't involve extending any class and is much less verbose (pretty much 3 lines). Taking a look to this sources and using fig.canvas.toolbar I made this snippet work:

    It plots an image and adds two buttons to the toolbar: previous and next, which can be bound to any parameter-less function. This can be very convenient, for instance, for scrolling through the images on a folder and drawing some points or lines on them using scatter, as explained in this other SO post. Let me know how it works for you!

    fig, ax = plt.subplots()
    fig.canvas.manager.toolbar._Button("PREVIOUS", "back_large", )
    fig.canvas.manager.toolbar._Button("NEXT", "forward_large", )
    im = plt.imread("hello.png")
    implot = ax.imshow(im)
    fig.show()
    

    • Note the bigger arrows that were added to the toolbar.

    • The drawback of this method is that it uses the protected _Button method, whose interface may change in further versions, but this way seems fine to me for some casual scripting.

    • Also note that the method signature (see the sources) requires a path to an image that (in my case) has to be found at /usr/local/lib/python2.7/dist-packages/matplotlib/mpl-data/images. Again, there is probably a way to overcome this but probably more verbose than the inheriting alternative.

    Cheers,
    Andres


    BONUS:

    class ImageViewer(object):
        """Given a path to a directory, this class opens a matplotib window with two
           custom buttons that allow scrolling through the images in the directory.
           Usage example: iv = ImageViewer("/home/pau/Images")
        """
        def __init__(self, seq_path, img_extension=".png"):
            self.ids = [join(seq_path, splitext(img)[0]) for img in listdir(seq_path)
                        if img.endswith(img_extension)]
            self.mod = len(self.ids)
            self.idx = 0
            self.fig, self.ax = plt.subplots()
            self.fig.canvas.manager.toolbar._Button("PREVIOUS", "back_large", self.prev)
            self.fig.canvas.manager.toolbar._Button("NEXT", "forward_large", self.next)
            self._plot(0)
        def _plot(self, idx):
            im = plt.imread(self.ids[idx]+".png")
            implot = self.ax.imshow(im, cmap='Greys_r',  interpolation='nearest')
            self.fig.show()
        def next(self):
            self.idx = (self.idx+1)%self.mod
            self._plot(self.idx)
        def prev(self):
            self.idx = (self.idx-1)%self.mod
            self._plot(self.idx)
    

提交回复
热议问题