Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get matplotlib figures in emf/wmf format?

How can I get matplotlib plots as emf or wmf files that are usable as vector graphics in MS Office (Word and PowerPoint)?

I've tried exporting to svg and converting to emf using both Inkscape and LibreOffice Draw, but both of those options seem to cause image quality loss resulting in raster images.

I've also tried exporting to pdf and converting to emf/wmf, but that has the same issue.

like image 237
iamchoosinganame Avatar asked Nov 07 '18 18:11

iamchoosinganame


2 Answers

Here is my solution to create WMF and SVG. You can install Inkscape and use the following class, 'SaveAndClosePlot' creates SVG and then by using the Inkscape it converted to WMF. TestPlot function can be customized for your need.

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
like image 176
Kayhan Avatar answered Oct 26 '22 23:10

Kayhan


To save figures as .emf file in matplotlib using Linux, try the following:

  1. Install Inkscape (I have installed Inkscape 0.92.4 in Ubuntu 16.04. Other versions should work alike)
  2. In matplotlib, save the figure as .svg and then convert it to .emf via an Inkscape subprocess call. For example:
    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)

You can then insert the .emf figure as a picture in MS Word or PowerPoint. The quality is near .svg. Be warned though, large .svg files may not work.

like image 39
Sam Macharia Avatar answered Oct 26 '22 23:10

Sam Macharia