如何在Matplotlib图形窗口中轻松修改导航工具栏?

20

是否可能像以下示例一样修改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()

非常感谢。


1
这篇文章http://dalelane.co.uk/blog/?p=778有帮助吗? - halex
好的,我之前看过这个解决方案。如果可能的话,我正在寻找更简单的东西。我有一种感觉,直接编辑导航工具栏对象可能是不可能的,所以我可能不得不采用你提到的解决方案。谢谢 :-) - JBT
6个回答

28
我找到了一种方法来移除不需要的工具栏项,那就是创建一个子类,并在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')]

如果您想创建自定义按钮,应该查看backend_bases中NavigationToolbar2的定义。您可以轻松地将自己的条目添加到toolitems列表中,并在工具栏子类中定义适当的回调函数。请注意保留HTML标签。

天才的解决方案! - SAAD
1
也适用于NavigationToolbar2QT。 - Hashimoto
4
不需要子类化工具栏,只需使用 ToolManager这里有一个不错的例子 - Trevin Avery

8
使用 MPL 1.2.1,可以通过 figure.canvas.toolbar 获得标准 MPL 图形的导航工具栏句柄。我不确定之前的版本是否可以。
至少在 QT 后端中,可以使用 QT 方法 .addWidget() 将任意小部件添加到导航工具栏。我想其他后端使用类似的方法也可以,但我没有测试过。
这是一个使用 QT 后端的工作示例,它将 QLineEdit() 添加到导航工具栏中以更改 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()

2

之前的答案虽然可行,但非常依赖于后端。稍微更优雅的解决方案是通过子类化NavigationToolbar2来完成,就像这个回答中所做的那样:Matplotlib/Tkinter - customizing toolbar tooltips。在那里,目的是改变工具提示,但添加或删除按钮同样容易。


1
使用PyQt5和matplotlib版本'3.0.2'
如果您想添加一些按钮,只需按照由类NavigationToolbar2()提供的文档进行操作,该类在从matplotlib.backends.backend_qt5agg导入的NavigationToolbar2QT()中初始化:
# 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
# )

所以,如之前所述,您需要重新定义您的类(您也可以在下面看到当前可用的预定义按钮)。在我的情况下,我想要删除两个按钮(“保存”和“子图”,我已经注释掉了),因此代码如下:

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)

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

0

我发现只是那样

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

已经努力删除了所有工具,逐个弹出工具也可以。话虽如此,

toolbar.toolitems=[]

没有起作用,所以代码必须在其他地方引用了这个数组。


我刚试图弹出其中一个工具,虽然该工具已从toolbar.toolitems中移除,但它仍然显示在图形中。 - alwaysCurious

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接