在matplotlib的工具栏

时间:2016-05-29 04:45:15

标签: python matplotlib pyqt4

我使用PyQt在QMainWindow中创建了一个matplotlib图,我试图在我的代码中为matplotlib的工具栏添加一个按钮。这是我创建的NavigationToolbar

enter image description here

我使用addWidget方法添加了这些按钮。但是,我需要的是创建一个Icon并将其放在工具栏上。这是我的代码的一部分:

class A(QMainWindow):
  def __init__(self):
    QMainWindow.__init__(self)

    self.mainWidget = QWidget()
    self.setCentralWidget(self.mainWidget)
    layout = QVBoxLayout()
    self.mainWidget.setLayout(layout)

    self.figure_canvas = FigureCanvas(Figure())
    layout.addWidget(self.figure_canvas, 10)

    self.axes = self.figure_canvas.figure.add_subplot(111)

    self.navigation_toolbar = NavigationToolbar2(self.figure_canvas, self)
    self.addToolBar(Qt.TopToolBarArea, self.navigation_toolbar) 

    self.btn_selection_tool3 = QPushButton(, "Connect")
    self.navigation_toolbar.addWidget(self.btn_selection_tool3)

    self.btn_selection_tool2 = QPushButton()
    self.navigation_toolbar.addWidget(self.btn_selection_tool2)

    self.btn_showgrid = QPushButton("Show Grid")
    self.navigation_toolbar.addWidget(self.btn_showgrid)

    self.btn_hidegrid = QPushButton("Hide Grid")
    self.navigation_toolbar.addWidget(self.btn_hidegrid)

app = QApplication(sys.argv)
window = A()
window.show()
sys.exit(app.exec_())

我看到了一些代码和问题,我发现了这些,但我无法完成我需要的东西。这些是我读过的链接:

dale lane - customize navigation toolbar

Modify the toolbar

这些链接只告诉我如何删除其中一些,而且一个与wx一起使用。

如何在不使用QPushbuttonaddWidget方法的情况下在工具栏中添加这些按钮?希望你能帮帮我

------编辑------

基于@three_pineapples评论,我试过将这个类添加到我的代码中:

class MyToolbar(NavigationToolbar2):
  def __init__(self):
    NavigationToolbar2.__init__(self)
    self.iconDir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
        "..", "images", "icons", "")

    self.a = self.addAction(QIcon(iconDir + "BYE2.ico"),
        "Bye", self.bye)
    self.a.setToolTip("GoodBye")

  def bye(self):
    print "See you next time")

我实例化了:

self.navigation_toolbar = MyToolbar(),而不是:

self.navigation_toolbar = NavigationToolbar2(self.figure_canvas, self)

但是,我收到了这个错误:

TypeError: __init__() takes at least 3 arguments (1 given)

我已尝试添加*argskwargs,但我不知道我在这里缺少什么。

这是将按钮添加到matplotlib工具栏的方法吗?希望您能够帮助我。

2 个答案:

答案 0 :(得分:1)

我已经解决了这个问题。我找到了这段代码:

Matplotlib/Tkinter - customizing toolbar tooltips

所以,我创建了一个子类,并在链接中添加了它。这是代码:

class MyToolbar(NavigationToolbar2):
  def __init__(self, figure_canvas, parent= None):
    self.toolitems = (('Home', 'Lorem ipsum dolor sit amet', 'home', 'home'),
        ('Back', 'consectetuer adipiscing elit', 'back', 'back'),
        ('Forward', 'sed diam nonummy nibh euismod', 'forward', 'forward'),
        (None, None, None, None),
        ('Pan', 'tincidunt ut laoreet', 'move', 'pan'),
        ('Zoom', 'dolore magna aliquam', 'zoom_to_rect', 'zoom'),
        (None, None, None, None),
        ('Subplots', 'putamus parum claram', 'subplots', 'configure_subplots'),
        ('Save', 'sollemnes in futurum', 'filesave', 'save_figure'),
        ('Port', 'Select', "select", 'select_tool'),
        )

    NavigationToolbar2.__init__(self, figure_canvas, parent= None)

  def select_tool(self):
    print "You clicked the selection tool"

然后,您可以通过编写:

添加此工具栏
self.navigation_toolbar = MyToolbar(self.figure_canvas, self)            
self.navigation_toolbar.update()

如果您只想使用自己的按钮,则必须清除self.toolitems中的所有其他项目。例如:

self.toolitems = (
    ('Port', 'Select', "select", 'select_tool'),
    )

这样,您只能在NavigationToolbar

中看到自己的按钮

希望这有帮助。

答案 1 :(得分:0)

基于this related SO answer,我想要一种不涉及扩展任何类的方式,并且更不那么详细(相当多3行) 。看一下这个sources并使用fig.canvas.toolbar我制作了这个代码段:

绘制图像并在工具栏中添加两个按钮:上一个和下一个,可以绑定到任何无参数功能。这可以非常方便,例如,滚动文件夹上的图像并使用scatter在其上绘制一些点或线,如this other SO post中所述。让我知道它对你有用!

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

enter image description here

  • 请注意添加到工具栏中的较大箭头。

  • 这种方法的缺点是它使用受保护的_Button方法,其接口可能会在更多版本中发生变化,但这种方式对我来说似乎很适合一些随意的脚本。

  • 另请注意,方法签名(请参阅参考资料)需要图像的路径(在我的情况下)必须在/usr/local/lib/python2.7/dist-packages/matplotlib/mpl-data/images找到。同样,可能有一种方法可以克服这个问题,但可能比继承替代方案更冗长。

干杯,
安德烈

奖金:

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)