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

How to add clipboard support to Matplotlib figures?

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

这个选项可以很容易地添加到 Matplotlib 图形中吗?最好是,所有 MPL 数字都应自动受益于此功能。

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

是的,可以。这个想法是用一个自定义的 plt.figure 替换默认值(一种称为 monkey patching 的技术),它注入一个键盘处理程序以复制到剪贴板。以下代码将允许您通过按 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()

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

EelkeSpaak 的解决方案打包在一个不错的模块中: addcopyfighandler

只需pip install addcopyfighandler安装,导入matplotlib或pyplot后导入模块

最后的评论很有用。

  1. 安装包

    pip install addcopyfighandler

  2. 导入matplotlib后导入模块,例如:

    import matplotlib.pyplot as plt
    import matplotlib.font_manager as fm
    from matplotlib.cm import get_cmap
    import addcopyfighandler

  3. 使用ctr + C将图复制到剪贴板

尽情享受吧。

基于 中描述的解决方案,我们可以编写一个函数来代替 monkey-patching matplotlib 的图 class:

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。