2

Is there a way to change the size of NavigationToolbar (e.g. the size of zoom button) when embedding matplotlib into Tkinter? I have tried to set the keywords width and height in config, but it did not work. So, any suggestion?

Update

import matplotlib
import os
import Tkinter as tk

from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg as NavigationToolbar
from matplotlib.backends.backend_tkagg import ToolTip

class CustomedToolbar(NavigationToolbar):
    def __init__(self, canvas, root):
        NavigationToolbar.__init__(self,canvas,root)

def _Button(self, text, file, command, extension='.ppm'):
    img_file = os.path.join(matplotlib.rcParams['datapath'], 'images', file + extension)
    im = tk.PhotoImage(master=self, file=img_file)
    im = im.zoom(3, 3)
    im = im.subsample(4, 4)
    # Do stuff with im here
    b = tk.Button(master=self, text=text, padx=2, pady=2, image=im, command=command)
    b._ntimage = im
    b.pack(side=tk.LEFT)
    return b

def _init_toolbar(self):
    xmin, xmax = self.canvas.figure.bbox.intervalx
    height, width = 50, xmax-xmin
    tk.Frame.__init__(self, master=self.window,
                                            width=int(width), height=int(height),
                                            borderwidth=2)

    self.update()  # Make axes menu

    for text, tooltip_text, image_file, callback in self.toolitems:
        if text is None:
            # spacer, unhandled in Tk
            pass
        else:
            button = self._Button(text=text, file=image_file, command=getattr(self, callback))
            if tooltip_text is not None:
                ToolTip.createToolTip(button, tooltip_text)

    self.message = tk.StringVar(master=self)
    self._message_label = tk.Label(master=self, textvariable=self.message)
    self._message_label.pack(side=tk.RIGHT)
    self.pack(side=tk.BOTTOM, fill=tk.X)

This is my effort. Thanks fhdrsdg.

5
  • Could you provide a mcve or an image of the problem you are experiencing together with a clear statement of what you would want to achieve? The way your question is now makes it (at least for me) difficult to understand what your problem exactly is. Commented Jan 8, 2015 at 11:00
  • @fhdrsdg Thanks for your reply and reminding. The question is refined. Commented Jan 8, 2015 at 11:41
  • @fhdrsdg I'm sorry I can not add more comments after your answer, so I have to add my comment here. +1 for your anwser as it works. But sadly, only integers are accepted by im.subsample or im.zoom. And PIL is not standardard library in python. So if I do not use any third-party packages, I found your solution is the only way I can choose. Commented Jan 8, 2015 at 15:51
  • You could try combinations like im = im.zoom(2, 2) im = im.subsample(3, 3) to get the images at 2/3 of the size. But that doesn't really improve image quality. Commented Jan 8, 2015 at 15:58
  • Great idea! May be I have to use another images instead of matplotlib image or process the images using other powerful image processing software. Thanks again. Commented Jan 8, 2015 at 16:08

1 Answer 1

1

If I understand what you want correctly, you can create a custom toolbar class, which inherits from NavigationToolbar2TkAgg. You can the alter the _Button definition in which the buttons are created:

class CustomToolbar(NavigationToolbar2TkAgg):
    def _Button(self, text, file, command, extension='.ppm'):
        img_file = os.path.join(matplotlib.rcParams['datapath'], 'images', file + extension)
        im = Tk.PhotoImage(master=self, file=img_file)
        # Do stuff with im here
        b = Tk.Button(
            master=self, text=text, padx=2, pady=2, image=im, command=command)
        b._ntimage = im
        b.pack(side=Tk.LEFT)
        return b

As you can see, here we have an image file im, which is the image you want to make smaller. Tk.PhotoImage only has subsample() to do this, which lets you shrink the images by a whole factor. For example you could do im = im.subsample(2, 2) to make the images twice as small (or im = im.zoom(2, 2) to make them twice as big).

Maybe someone who is more proficient with PIL could tell you if there's a way to use PIL to make the images any size you want, but I couldn't get that to work.

Sign up to request clarification or add additional context in comments.

4 Comments

Yes, this is what I want to do and I'll try. One more question is why set keywords width and height of the attribute config does not work?
What object did you call config on?
toolbar = NavigationToolbar2TkAgg(canvas, root). The toolbar has attribute config.
I think config configures the frame in which the buttons are, so changing the size of this frame does nothing about the size of the buttons. For me, width and height do nothing at all, which I suspect has something to do with this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.