¿Cómo modificar la barra de herramientas de navegación fácilmente en una ventana de figura de matplotlib?

¿Es posible hacer algo como lo siguiente para modificar la barra de herramientas de navegación en matplotlib?

  1. Generar una ventana de figura, con: fig = figure()
  2. Obtenga una referencia de la barra de herramientas de navegación con: tbar = fig.get_navigation_toolbar() , o mejor aún, solo con: tbar = fig.navtbar
  3. Modifique la barra de herramientas a través de la barra de referencia tbar , como eliminar / agregar / editar un botón con algo como esto:
    tbar.add_button();
    tbar.remove_button(a reference to a button);
    tbar.edit_button(a reference to a button);
  4. Actualiza la figura con: fig.canvas.draw()

Muchas gracias.

La forma en que encontré para eliminar los elementos no deseados de la barra de herramientas es crear una subclase, que se crea una instancia y se utiliza en una aplicación GTK. Al crear manualmente los objetos Figure, FigureCanvas y NavigationToolbar de todos modos, esta era la forma más fácil.

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

Si desea crear botones personalizados, debería echar un vistazo a la definición de NavigationToolbar2 en backend_bases. Puede agregar fácilmente sus propias entradas a la lista de elementos de toolitems y definir las funciones de callback adecuadas en la subclase de su barra de herramientas.

Con MPL 1.2.1 es posible obtener un controlador de la barra de herramientas de navegación de una figura MPL estándar a través de figure.canvas.toolbar . No estoy seguro de las versiones anteriores.

Al menos con el backend QT es posible agregar widgets arbitrarios a la barra de herramientas de navegación usando el método QT .addWidget() . Supongo que otros backends funcionarán usando métodos similares, pero no los he probado.

Aquí es un ejemplo de trabajo (usando el backend QT) que agrega un QLineEdit() a la barra de herramientas de navegación para cambiar el título de una figura de MPL (ejecutada desde IPython (pylab) con run -i ... , luego ejecute 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() 

Las respuestas anteriores funcionan pero son muy específicas para el backend. Una solución ligeramente más elegante es subclase NavigationToolbar2, como se hace en esta otra respuesta: Matplotlib / Tkinter: personalización de la información sobre herramientas de la barra de herramientas. El objective era cambiar la información sobre herramientas, pero agregar o eliminar un botón es igualmente trivial.

Además de la solución anterior de torfbotl, es posible que tenga un botón adicional colgado al final (el que tiene la marca de verificación verde).

Eso se puede mitigar en el constructor de la subclase:

 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 

Encontré que solo eso

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

se trabajó para eliminar todas las herramientas y también se usaron herramientas individuales. Dicho esto,

 toolbar.toolitems=[] 

no funcionó, por lo que el código debe tener otra referencia a esta matriz en algún lugar.

Usando PyQt5 y matplotlib versión ‘3.0.2’

Si desea agregar algunos botones, simplemente siga el documento proporcionado por la clase NavigationToolbar2 () que se inicializa en NavigationToolbar2QT () que se importa desde matplotlib.backends.backend_qt5agg:

 # 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 # ) 

Por lo tanto, debe redefinir su clase como se dijo anteriormente (también puede ver debajo, los botones predefinidos disponibles en el cajero automático). En mi caso quise eliminar 2 botones (‘Guardar’ y ‘Subplots’ que comenté) para que me dieran:

 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'), ) 

Y llamando a NavigationToolbar2QT (aún en mi caso):

 figure = plt.figure() canvas = FigureCanvas(figure) toolbar = NavigationToolbar2QT(canvas, self)