18

是否可以执行以下操作来修改 matplotlib 中的导航工具栏?

  1. 生成一个图形窗口,其中:fig = figure()
  2. 获取导航工具栏的参考,使用:tbar = fig.get_navigation_toolbar(),或者更好的是,只需:tbar = fig.navtbar
  3. 通过引用修改工具栏tbar,例如删除/添加/编辑按钮,如下所示:
       tbar.add_button(<a Button object>);
       tbar.remove_button(a reference to a button);
       tbar.edit_button(a reference to a button);
  4. 用以下内容更新图形:fig.canvas.draw()

非常感谢。

4

6 回答 6

25

我发现删除不需要的工具栏项的方法是创建一个子类,该子类在 GTK 应用程序中被实例化并使用。无论如何,当我手动创建 Figure、FigureCanvas 和 NavigationToolbar 对象时,这是最简单的方法。

class NavigationToolbar(NavigationToolbar2GTKAgg):
    # only display the buttons we need
    toolitems = [t for t in NavigationToolbar2GTKAgg.toolitems if
                 t[0] in ('Home', 'Pan', 'Zoom', 'Save')]

如果你想创建自定义按钮,你应该看看NavigationToolbar2backend_bases 中的定义。您可以轻松地将自己的条目添加到toolitems列表中,并在工具栏子类中定义适当的回调函数。

于 2013-03-21T14:01:34.283 回答
7

使用 MPL 1.2.1 可以获得标准 MPL 图的导航工具栏的处理程序figure.canvas.toolbar。我不确定以前的版本。

至少使用 QT 后端,可以使用 QT 方法将任意小部件添加到导航工具栏.addWidget()。我想其他后端也可以使用类似的方法,但我还没有测试过它们。

这是一个工作示例(使用 QT 后端),它QLineEdit()向导航工具栏添加 a 以更改 MPL 图的标题(从 IPython (pylab) 运行run -i ...,然后启动test()):

from PySide import QtGui, QtCore

def test():
    plot([1,2,3], lw=2)
    q = qt4_interface(gcf())
    return q   # WARNING: it's paramount to return the object otherwise, with 
               # no references, python deletes it and the GUI doesn't respond!

class qt4_interface:
    def __init__(self,fig):
        self.fig = fig

        toolbar = fig.canvas.toolbar
        self.line_edit = QtGui.QLineEdit()
        toolbar.addWidget(self.line_edit)
        self.line_edit.editingFinished.connect(self.do_something) 

    def do_something(self, *args):
        self.fig.axes[0].set_title(self.line_edit.text())
        self.fig.canvas.draw()
        #f = open('l','a'); f.write('yes\n'); f.flush(); f.close()
于 2013-06-28T22:45:41.937 回答
2

以前的答案有效,但非常特定于后端。一个稍微更优雅的解决方案是继承 NavigationToolbar2,就像在另一个答案中所做的那样:Matplotlib/Tkinter - 自定义工具栏工具提示 目的是更改工具提示,但添加或删除按钮同样微不足道。

于 2015-02-18T13:40:45.840 回答
1

除了上面 torfbotl 的解决方案之外,您可能还会在末尾挂一个额外的按钮(带有绿色复选标记的那个)。

这可以在子类构造函数中得到缓解:

from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar

class PanOnlyToolbar(NavigationToolbar):
    # only display the buttons we need
    toolitems = [t for t in NavigationToolbar2GTKAgg.toolitems if
                 t[0] in ("Pan", )]

    def __init__(self, *args, **kwargs):
        super(PanOnlyToolbar, self).__init__(*args, **kwargs)
        self.layout().takeAt(1)  #or more than 1 if you have more buttons
于 2014-04-11T03:50:57.593 回答
1

使用 PyQt5 和 matplotlib 版本 '3.0.2'

如果您想添加一些按钮,只需按照从 matplotlib.backends.backend_qt5agg 导入的 NavigationToolbar2QT() 中初始化的类 NavigationToolbar2() 给出的文档:

# list of toolitems to add to the toolbar, format is:
# (
#   text, # the text of the button (often not visible to users)
#   tooltip_text, # the tooltip shown on hover (where possible)
#   image_file, # name of the image for the button (without the extension)
#   name_of_method, # name of the method in NavigationToolbar2 to call
# )

因此,您需要重新定义您的类,如前所述(您还可以在下面看到可用的预定义按钮)。就我而言,我想删除 2 个按钮(我评论的“保存”和“子图”),这样我就得到了:

class NavigationToolbar2QT(NavigationToolbar2QT):
    # only display the buttons we need
    NavigationToolbar2QT.toolitems = (
        ('Home', 'Reset original view', 'home', 'home'),
        ('Back', 'Back to previous view', 'back', 'back'),
        ('Forward', 'Forward to next view', 'forward', 'forward'),
        (None, None, None, None),
        ('Pan', 'Pan axes with left mouse, zoom with right', 'move', 'pan'),
        ('Zoom', 'Zoom to rectangle', 'zoom_to_rect', 'zoom'),
        # ('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'),
        (None, None, None, None),
        # ('Save', 'Save the figure', 'filesave', 'save_figure'),
    )

并调用 NavigationToolbar2QT(在我的情况下):

figure = plt.figure()
canvas = FigureCanvas(figure)
toolbar = NavigationToolbar2QT(canvas, self)
于 2019-04-04T15:43:20.080 回答
0

我发现就是这样

fig = plt.figure()
toolbar = fig.canvas.manager.toolbar
tb=toolbar.toolitems
while len(tb)>0:
    tb.pop(0)

努力删除所有工具,并且弹出单个工具也有效。也就是说,

toolbar.toolitems=[]

没用,所以代码必须在某处对该数组有另一个引用。

于 2018-08-03T16:27:51.440 回答