You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Matplotlib/Seaborn图像像截图一样复制到内存?

解决Seaborn热力图复制到剪贴板(截图式粘贴)的问题

你之前的代码只是将PNG字节流直接通过pbcopy复制,但系统剪贴板会将其识别为原始字节文本而非图像格式,导致无法像截图那样正常粘贴。需要针对不同系统的剪贴板机制,明确指定图像格式类型,以下是分平台的解决方案:

macOS 专属解决方案

使用AppleScript的ObjC绑定,直接将PNG数据写入剪贴板的图像类型:

def copy_fig_to_clipboard(fig: plt.figure, close: bool = False):
    import io
    from subprocess import run

    # 将Matplotlib figure保存为PNG字节流
    buf = io.BytesIO()
    fig.savefig(buf, format='png', facecolor='white')
    buf.seek(0)

    # 通过AppleScript设置剪贴板为PNG图像
    objc_script = '''
    set theImageData to current application's NSData's dataWithContentsOfFile:"-"
    set thePasteboard to current application's NSPasteboard's generalPasteboard()
    thePasteboard's clearContents()
    thePasteboard's setData:theImageData forType:(current application's NSPasteboardTypePNG)
    '''
    run(['osascript', '-l', 'ObjC', '-e', objc_script], input=buf.read(), check=True)

    print("图像已复制到剪贴板")
    if close:
        plt.close(fig)
        print("已关闭图像")
    else:
        print("图像未关闭")

Windows 专属解决方案

先安装依赖:pip install pywin32 pillow,将图像转换为Windows剪贴板支持的DIB格式:

def copy_fig_to_clipboard(fig: plt.figure, close: bool = False):
    import io
    import win32clipboard
    from PIL import Image

    buf = io.BytesIO()
    fig.savefig(buf, format='png', facecolor='white')
    buf.seek(0)
    img = Image.open(buf)

    # 转换为Windows剪贴板兼容的DIB格式
    output_buf = io.BytesIO()
    img.convert('RGB').save(output_buf, 'BMP')
    # 去除BMP文件头(前14字节),保留DIB数据
    dib_data = output_buf.getvalue()[14:]
    output_buf.close()

    win32clipboard.OpenClipboard()
    win32clipboard.EmptyClipboard()
    win32clipboard.SetClipboardData(win32clipboard.CF_DIB, dib_data)
    win32clipboard.CloseClipboard()

    print("图像已复制到剪贴板")
    if close:
        plt.close(fig)
        print("已关闭图像")

Linux 专属解决方案

先安装xclip工具(如Debian/Ubuntu:sudo apt install xclip),通过xclip指定图像格式复制:

def copy_fig_to_clipboard(fig: plt.figure, close: bool = False):
    import io
    from subprocess import run

    buf = io.BytesIO()
    fig.savefig(buf, format='png', facecolor='white')
    buf.seek(0)

    # 使用xclip将PNG数据写入剪贴板的图像类型
    run(['xclip', '-selection', 'clipboard', '-t', 'image/png', '-i'], input=buf.read(), check=True)

    print("图像已复制到剪贴板")
    if close:
        plt.close(fig)
        print("已关闭图像")

跨平台通用解决方案

自动识别系统并调用对应逻辑:

import sys
import io

def copy_fig_to_clipboard(fig: plt.figure, close: bool = False):
    # 保存figure为PNG字节流
    buf = io.BytesIO()
    fig.savefig(buf, format='png', facecolor='white')
    buf.seek(0)
    img_data = buf.read()

    if sys.platform == 'darwin':
        from subprocess import run
        objc_script = '''
        set theImageData to current application's NSData's dataWithContentsOfFile:"-"
        set thePasteboard to current application's NSPasteboard's generalPasteboard()
        thePasteboard's clearContents()
        thePasteboard's setData:theImageData forType:(current application's NSPasteboardTypePNG)
        '''
        run(['osascript', '-l', 'ObjC', '-e', objc_script], input=img_data, check=True)
    elif sys.platform == 'win32':
        import win32clipboard
        from PIL import Image
        img = Image.open(io.BytesIO(img_data))
        output_buf = io.BytesIO()
        img.convert('RGB').save(output_buf, 'BMP')
        dib_data = output_buf.getvalue()[14:]
        output_buf.close()
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardData(win32clipboard.CF_DIB, dib_data)
        win32clipboard.CloseClipboard()
    elif sys.platform.startswith('linux'):
        from subprocess import run
        run(['xclip', '-selection', 'clipboard', '-t', 'image/png', '-i'], input=img_data, check=True)
    else:
        raise NotImplementedError(f"不支持的系统平台: {sys.platform}")

    print("图像已复制到剪贴板")
    if close:
        plt.close(fig)
        print("已关闭图像")
    else:
        print("图像未关闭")

使用示例

import seaborn as sns
import matplotlib.pyplot as plt

# 生成热力图
flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")
fig, ax = plt.subplots()
sns.heatmap(flights, ax=ax)

# 复制到剪贴板
copy_fig_to_clipboard(fig, close=True)

内容的提问来源于stack exchange,提问作者anmol_gorakshakar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 12:45:56