How to modify the navigation toolbar easily in a matplotlib figure window?
Is it possible to do something like the following to modify the navigation toolbar in matplotlib?
- Generate a figure window, with:
fig = figure()
- Get a reference of the navigation tool-bar, with:
tbar = fig.get_navigation_toolbar()
, or better yet, just by:tbar = fig.navtbar
- Modify the tool-bar through the reference
tbar
, such as delete/add/edit a button with something like this:
tbar.add_button(<a Button object>);
tbar.remove_button(a reference to a button);
tbar.edit_button(a reference to a button);
- Update the figure with:
fig.canvas.draw()
Thank you very much.
Solution 1:
The way I found to remove unwanted toolbar items is making a subclass, which is instantiated and used in a GTK application. As I manually create Figure, FigureCanvas and NavigationToolbar objects anyway, this was the easiest way.
class NavigationToolbar(NavigationToolbar2GTKAgg):
# only display the buttons we need
toolitems = [t for t in NavigationToolbar2GTKAgg.toolitems if
t[0] in ('Home', 'Pan', 'Zoom', 'Save')]
If you want to create custom buttons, you should take a look on the definition of NavigationToolbar2
in backend_bases. You can easily add your own entries to the toolitems
list and define appropriate callback functions in your toolbar subclass.
Solution 2:
With MPL 1.2.1 it is possible to get an handler of the navigation toolbar of a standard MPL figure through figure.canvas.toolbar
. I'm not sure about previous versions.
At least with the QT backend it is possible to add arbitrary widgets to the navigation toolbar using the QT method .addWidget()
. I suppose other backends will work using similar methods, but I haven't tested them.
Here it is a working example (using the QT backend) that adds a QLineEdit()
to the navigation toolbar to change the title of a MPL figure (run from IPython (pylab) with run -i ...
, then launch 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()