pythonmatplotlibplotscipyclipboard

How to add clipboard support to Matplotlib figures?


In MATLAB, there is a very convenient option to copy the current figure to the clipboard. Although Python/numpy/scipy/matplotlib is a great alternative to MATLAB, such an option is unfortunately missing.

Can this option easily be added to Matplotlib figures? Preferably, all MPL figures should automatically benefit from this functionality.

I'm using MPL's Qt4Agg backend, with PySide.


Solution

  • Yes, it can. The idea is to replace the default plt.figure with a custom one (a technique known as monkey patching) that injects a keyboard handler for copying to the clipboard. The following code will allow you to copy any MPL figure to the clipboard by pressing Ctrl+C:

    import io
    import matplotlib.pyplot as plt
    from PySide.QtGui import QApplication, QImage
    
    def add_clipboard_to_figures():
        # use monkey-patching to replace the original plt.figure() function with
        # our own, which supports clipboard-copying
        oldfig = plt.figure
    
        def newfig(*args, **kwargs):
            fig = oldfig(*args, **kwargs)
            def clipboard_handler(event):
                if event.key == 'ctrl+c':
                    # store the image in a buffer using savefig(), this has the
                    # advantage of applying all the default savefig parameters
                    # such as background color; those would be ignored if you simply
                    # grab the canvas using Qt
                    buf = io.BytesIO()
                    fig.savefig(buf)
                    QApplication.clipboard().setImage(QImage.fromData(buf.getvalue()))
                    buf.close()
    
            fig.canvas.mpl_connect('key_press_event', clipboard_handler)
            return fig
    
        plt.figure = newfig
    
    add_clipboard_to_figures()
    

    Note that if you want to use from matplotlib.pyplot import * (e.g. in an interactive session), you need to do so after you've executed the above code, otherwise the figure you import into the default namespace will be the unpatched version.