I am looking for a way to save a matplotlib figure as an EMF file. Matplotlib allows me to save as either a PDF or SVG vector file but not as EMF.

After a long search I still cannot seem to find a way to do this with python. Hopefully anyone has an idea.

My workaround is to call inkscape using subprocess but this is far from ideal as I would like to avoid the use of external programs.

I'm running python 2.7.5 and matplotlib 1.3.0 using the wx backend.


Solution 1:

  • For anyone who still needs this, I wrote a basic function that can let you save a file as an emf from matplotlib, as long as you have inkscape installed.

I know the op didn't want inkscape, but people who find this post later just want to make it work.

import matplotlib.pyplot as plt
import subprocess
import os
inkscapePath = r"path\to\inkscape.exe"
savePath= r"path\to\images\folder"

def exportEmf(savePath, plotName, fig=None, keepSVG=False):
    """Save a figure as an emf file

    Parameters
    ----------
    savePath : str, the path to the directory you want the image saved in
    plotName : str, the name of the image 
    fig : matplotlib figure, (optional, default uses gca)
    keepSVG : bool, whether to keep the interim svg file
    """

    figFolder = savePath + r"\{}.{}"
    svgFile = figFolder.format(plotName,"svg")
    emfFile = figFolder.format(plotName,"emf")
    if fig:
        use=fig
    else:
        use=plt
    use.savefig(svgFile)
    subprocess.run([inkscapePath, svgFile, '-M', emfFile])
 
    if not keepSVG:
        os.system('del "{}"'.format(svgFile))

#Example Usage

import numpy as np
tt = np.linspace(0, 2*3.14159)
plt.plot(tt, np.sin(tt))
exportEmf(r"C:\Users\userName", 'FileName')

Solution 2:

I think the function is cool but inkscape syntax seems not working in my case. I search in other post and find it as:

inkscape filename.svg --export-filename filename.emf 

So if I replace -M by --export-filename within the subprocess argument, everything works fine.