Search code examples
pythonmatplotlibxfce

How can I display a matplotlib interactive window without any of the controls visible?


I need to display a PNG on a users Xfce4 desktop. So far I'm using a python script that shows the PNG in an interactive matplotlib window:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

img = mpimg.imread("My.png")
plt.imshow(img)
plt.show()

That is very unattractive though. Is there a way to remove all the interactive controls, all the border space (axis?) that gets put around the image, and resize the window to a particular width/height on startup?

Alternatively, is there a better option to provide a lightweight and static display of an image on a desktop? Doesn't have to be python/matplotlib of course.


Solution

  • Sure, but at that point, you might consider using a "bare" gui toolkit instead.

    At any rate, here's the matplotlib way:

    import matplotlib.pyplot as plt
    
    # Note that the size is in inches at 80dpi. 
    # To set a size in pixels, divide by 80.
    fig = plt.figure(figsize=(4, 5))
    
    # Now we'll add an Axes that takes up the full figure
    ax = fig.add_axes([0, 0, 1, 1])
    ax.axis('off') # Hide all ticks, labels, outlines, etc.
    
    # Display the image so that it will stretch to fit the size
    # of the figure (pixels won't be square)
    ax.imshow(plt.imread('test.png'), aspect='auto')
    
    plt.show()
    

    This does everything except for hiding the toolbar. To hide the toolbar, you'll need to be be backend-specific. You have two options: 1) Handle creating the window manually and embed the matplotlib canvas inside it, 2) hide the toolbar using backend-specific methods.

    As an example of hiding the toolbar, with the qt-based backends, you'd do:

    import matplotlib
    matplotlib.use('qt4agg')
    import matplotlib.pyplot as plt
    
    fig = plt.figure(figsize=(4, 5))
    ax = fig.add_axes([0, 0, 1, 1])
    ax.axis('off')
    
    ax.imshow(plt.imread('test.png'), aspect='auto')
    
    # qt specific!
    fig.canvas.toolbar.setVisible(False)
    
    plt.show()
    

    And for the Tk-backend, you'd do:

    import matplotlib
    matplotlib.use('tkagg')
    import matplotlib.pyplot as plt
    
    fig = plt.figure(figsize=(4, 5))
    ax = fig.add_axes([0, 0, 1, 1])
    ax.axis('off')
    
    ax.imshow(plt.imread('test.png'), aspect='auto')
    
    # Tk specific!
    fig.canvas.toolbar.pack_forget()
    
    plt.show()
    

    By contrast, if you wanted to skip matplotlib together and just use Tkinter, you'd do something like:

    import Tkinter as tk
    from PIL import ImageTk
    
    root = tk.Tk()
    
    im = ImageTk.PhotoImage(file='test.png')
    panel = tk.Label(root, image=im)
    panel.pack(fill=tk.BOTH, expand=True)
    
    root.mainloop()
    

    This displays the image at one-pixel-to-one-pixel on the screen and doesn't allow for resizing. However, it's about as minimal as you can get.