title: Changing the icon in matplotlib navigation toolbar using GTK backend
body: <p>Similar questions have been asked before on Stack Overflow, however, none of them involve the GTK backend, and none of them involve the need to change the path being searched by the backend. Similar questions here would include <a href="https://stackoverflow.com/questions/37506260/adding-an-item-in-matplotlib%C2%B4s-toolbar">this</a> and <a href="https://stackoverflow.com/questions/12695678/how-to-modify-the-navigation-toolbar-easily-in-a-matplotlib-figure-window?lq=1">this</a> among others. The relevant code for the GTK backend is <a href="https://github.com/matplotlib/matplotlib/blob/main/lib/matplotlib/backends/backend_gtk3.py" rel="nofollow noreferrer">here</a>.</p>
  <p>As an aside, in case it is relevant, I am freezing this Python script using PyInstaller, and the reason I want to &quot;change&quot; the icon is because on certain Windows computers I am finding that the icons are broken links for the Navigation Toolbar despite the images appearing in the correct location:</p>
  <pre><code>\dist\&lt;script name&gt;\matplotlib\mpl-data\images\&lt;image_file&gt;-symbolic.svg
  </code></pre>
  <p>as well as the images having the format expected by the GTK backend (<code>f'{image_file}-symbolic.svg'</code>). I am not sure why this problem is happening and have spent a lot of time getting nowhere, so I figured a possible fix might be to stash the images as part of my repot in a location of my choosing and forcing them to be used by the script (in case it is some weird environment variable or path issue). Using the example below, I can change the tooltip successfully and the image/icon, but I wouldn't be able to change the location of the image. The third argument of toolitems controls the image:</p>
  <pre><code>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
  )
  </code></pre>
  <p>Apparently the image must be in the path expected and must be a name without an extension. The code for the backend specifies:</p>
  <pre><code>image = Gtk.Image.new_from_gicon(
      Gio.Icon.new_for_string(
          str(cbook._get_data_path('images',
                                   f'{image_file}-symbolic.svg'))),
      Gtk.IconSize.LARGE_TOOLBAR)
  </code></pre>
  <p>So I can take an svg image and put it in the path I gave above, with the appended <code>-symbolic</code> at the end and get this to work. However, is there a way to do this in a path different than the default directory fed to the backend? The code that I am currently using is below:</p>
  <pre><code>from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3
  
  class MyToolbar(NavigationToolbar2GTK3):
    def __init__(self, figure_canvas, window):
      self.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'),
          )
  
      NavigationToolbar2GTK3.__init__(self, figure_canvas, window)
  
  self.navigation_toolbar = MyToolbar(self._gtkFigure, main)
  self.navigation_toolbar.update()
  </code></pre>
  <p>My expectation is that the broken links coming up on some computers are the result of <code>cbook._get_data_path</code> (used by the backend) coming up different for some reason, so if I could change this in the script somehow, perhaps I can patch the problem? Any assistance or pointers would be appreciated!</p>
  <p>Edit: After digging some more it looks like <code>_get_data_path</code> in cbook is just a call to <code>matplotlib.get_data_path()</code>. From <a href="https://github.com/matplotlib/matplotlib/issues/16678" rel="nofollow noreferrer">here</a> it doesn't appear using a custom data path is possible in matplotlib (I was looking for a <code>.set_data_path()</code> method). One of the contributors suggests &quot;grab the native tk widgets and perform the right calls to <code>iconphoto()</code> and friends on them.&quot; Since I am not using the Tkinter backend I am still not sure how to proceed. I am fairly certain that the method I outlined above will not work, and another method is required, similar to <a href="https://stackoverflow.com/questions/10189590/change-icon-in-a-matplotlib-figure-window">here</a>.</p>