如何获取 emf/wmf 格式的 matplotlib 图形?

How to get matplotlib figures in emf/wmf format?

如何将 matplotlib 绘图作为 emf 或 wmf 文件,以便在 MS Office(Word 和 PowerPoint)中用作矢量图形?

我尝试使用 Inkscape 和 LibreOffice Draw 导出为 svg 并转换为 emf,但这两个选项似乎都会导致图像质量下降,从而导致光栅图像。

我也试过导出为 pdf 并转换为 emf/wmf,但同样的问题。

这是我创建 WMF 和 SVG 的解决方案。您可以安装 Inkscape 并使用以下 class、'SaveAndClosePlot' 创建 SVG,然后使用 Inkscape 将其转换为 WMF。 TestPlot 函数可以根据您的需要进行自定义。

import os
from pathlib import Path
from ConfigParserM import logging
import subprocess
from matplotlib import pyplot as plt


class SVG_WMF_Plot:

    def __init__(self):
        self.__folderNameGraph = 'Graphs'
        self.__WMF_SVGSaving = True
        self.__inkScapePath = "C://Program Files//inkscape//inkscape.exe"
        self.__figureDPI = 500

    def getRootDirectory(self):
        try:
            return Path(os.path.dirname(os.path.realpath('__file__')))

        except Exception as e:
            logging.exception(e)
            raise

    def getAddressTo(self, Main=None, FolderName=None, FileName=None, Extension=None):
        try:
            if Main is None:
                Main = self.getRootDirectory()
            if FolderName:
                Path1 = Path(Main) / Path(FolderName)
            else:
                Path1 = Path(Main)

            if not os.path.exists(Path1):
                os.makedirs(Path1)
            if FileName:
                if Extension:
                    File_Address = Path1 / Path(FileName + "." + Extension)
                else:
                    File_Address = Path1 / Path(FileName)
            else:
                File_Address = Path1
            return File_Address

        except Exception as e:
            logging.exception(e)
            raise

    def TestPlot(self):
        try:

            fig, ax1 = plt.subplots()
            x = [1, 2]
            y = [1, 2]
            F1 = 'test'
            ax1.plot(x, y)
            self.SaveAndClosePlot(folderName=self.__folderNameGraph, fileName=F1)


        except Exception as e:
            logging.exception(e)
            raise

    def SaveAndClosePlot(self, folderName, fileName):
        try:
            Address = self.getAddressTo(FolderName=self.__folderNameGraph + f"\{folderName}", FileName=fileName, Extension="jpg")
            plt.savefig(Address, format='jpg', dpi=self.__figureDPI, bbox_inches='tight')

            if self.__WMF_SVGSaving:
                Address = self.getAddressTo(FolderName=self.__folderNameGraph + f"\{folderName}", FileName=fileName, Extension="svg")
                plt.savefig(Address, format='svg', dpi=self.__figureDPI, bbox_inches='tight')
                # add removing SVG if needed

                AddressWMF = self.getAddressTo(FolderName=self.__folderNameGraph + f"\{folderName}", FileName=fileName, Extension="wmf")
                subprocess.call([self.__inkScapePath, str(Address.resolve()), '--export-wmf', str(AddressWMF.resolve())])

            plt.clf()
            plt.close()
        except Exception as e:
            logging.exception(e)
            raise

要使用 Linux 在 matplotlib 中将图形保存为 .emf 文件,请尝试以下操作:

  1. 安装 Inkscape(我有 installed Inkscape 0.92.4 in Ubuntu 16.04。其他版本应该类似)
  2. matplotlib中,将图形保存为.svg,然后通过Inkscape 子进程调用将其转换为.emf。 例如:
    import numpy as np
    import subprocess
    import matplotlib.pyplot as plt
    
    x = np.arange(2,50,step=2)
    y = x**2
    plt.plot(x,y)
    plt.savefig('y_is_x^2.svg', format='svg', bbox_inches='tight')
    subprocess.call('inkscape y_is_x^2.svg -M y_is_x^2.emf',shell=True)

然后您可以将 .emf 图形作为图片插入 MS Word 或 PowerPoint 中。质量接近 .svg。不过请注意,大型 .svg 文件可能无法正常工作。