Python 如何向Matplotlib图形添加剪贴板支持?

Python 如何向Matplotlib图形添加剪贴板支持?,python,matplotlib,plot,scipy,clipboard,Python,Matplotlib,Plot,Scipy,Clipboard,在MATLAB中,有一个非常方便的选项可以将当前图形复制到剪贴板。尽管Python/numpy/scipy/matplotlib是MATLAB的一个很好的替代品,但遗憾的是,这样一个选项缺失了 此选项是否可以轻松添加到Matplotlib图形中?优选地,所有MPL图应自动受益于此功能 我正在使用MPL的Qt4Agg后端和PySide。是的,它可以。其想法是将默认的plt.figure替换为自定义的(一种称为的技术),该技术注入一个键盘处理程序,用于复制到剪贴板。以下代码允许您通过按Ctrl+C将

在MATLAB中,有一个非常方便的选项可以将当前图形复制到剪贴板。尽管Python/numpy/scipy/matplotlib是MATLAB的一个很好的替代品,但遗憾的是,这样一个选项缺失了

此选项是否可以轻松添加到Matplotlib图形中?优选地,所有MPL图应自动受益于此功能


我正在使用MPL的Qt4Agg后端和PySide。

是的,它可以。其想法是将默认的
plt.figure
替换为自定义的(一种称为的技术),该技术注入一个键盘处理程序,用于复制到剪贴板。以下代码允许您通过按Ctrl+C将任何MPL图形复制到剪贴板:

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

请注意,如果要使用matplotlib.pyplot import*中的
(例如,在交互式会话中),则需要在执行上述代码后执行此操作,否则导入默认命名空间的
图将是未修补的版本。

EelkeSpaak的解决方案打包在一个漂亮的模块中:


只需通过
pip install addcopyfighandler安装,然后在导入matplotlib或pyplot后导入模块。

最后的注释非常有用

  • 使用安装包

    pip安装addcopyfighandler

  • 导入matplotlib后再导入模块,例如:

    将matplotlib.pyplot导入为plt

    将matplotlib.font\u管理器作为fm导入
    
    从matplotlib.cm导入获取cmap

    import addcopyfighandler

  • 使用
    ctr+C
    将图形复制到剪贴板


  • 享受。

    基于中所述的解决方案,我们可以编写一个函数来完成这项工作,而不是对matplotlib的Figure类进行修补:

    import io
    import matplotlib.pyplot as plt
    import numpy as np
    
    from PyQt5.QtGui import QImage
    from PyQt5.QtWidgets import QApplication
    
    # Example figure.
    fig, ax = plt.subplots()
    X = np.linspace(0, 2*np.pi)
    Y = np.sin(X)
    ax.plot(X, Y)
    
    def add_figure_to_clipboard(event):
        if event.key == "ctrl+c":
           with io.BytesIO() as buffer:
                fig.savefig(buffer)
                QApplication.clipboard().setImage(QImage.fromData(buffer.getvalue()))
    
    fig.canvas.mpl_connect('key_press_event', add_figure_to_clipboard)
    

    请注意,此变体使用Qt5。

    对于我来说,似乎无法通过
    fig.savefig(buf,format='svg')
    选择格式。我得到的图像仍然是位图图像。我在win 7 64上使用带有matplotlib 2.2.2、Qt4Agg后端的python 36。我认为这是因为QImage将其渲染为位图。所以真正的问题是,如何复制像svg这样的粘贴向量格式的图像?