Search code examples
pythonpdfmatplotlibpdf-generationcoreldraw

Matplotlib output to PDF for Corel Draw


Update: The fonts issue was actaully solved by using rc("pdf", fonttype=42) but unfortunately it is combined with another - whenever is used any type of marker I tried CorelDraw comes with error "File is corrupted".

When I output my charts from Matplotlib into PDF I am not able to open it in Corel Draw. I highly suspect that the major issue might be with texts / fonts.

Simple code example which I need update to make PDF with text and markers import correctly in Corel Draw:

from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
from matplotlib import rc
rc("pdf", fonttype=42)

with PdfPages("simple.pdf") as pdf:
  points_y = points_x = [1,2,3]
  plt.plot(points_x, points_y, marker="o")
  pdf.savefig()
  plt.close()

Example of Corel vs Matplotlib / PDF Reader when not used rc("pdf", fonttype=42) and marker. If marker used PDF doesn't open and CorelDraw says "File is corrupted". Example of Corel vs Matplotlib / PDF Reader


Solution

  • It turned out there are two important issues which ruins import of Matplotlib generated PDF into CorelDraw.

    1. Setting up the font type from the default rc("pdf", fonttype=3) to rc("pdf", fonttype=42)
    2. Not using multiple markers. Only one marker per plot allowed! Possible to replace by text. (no pyplot.scatter, not in pyplot.plot etc.). When using any markers in number of 2 or more per plot CorelDraw finds the PDF corrupted and wont open it at all.

    Code rewritten to plot only one marker per plot plus only one marker in the legend:

    from matplotlib.backends.backend_pdf import PdfPages
    import matplotlib.pyplot as plt
    from matplotlib import rc
    rc("pdf", fonttype=42)
    
    with PdfPages("simple.pdf") as pdf:
        points_y = points_x = [1,2,3]
        plt.plot(points_x, points_y,color="r")
        # plot points one be one otherwise "File is corrupted" in CorelDraw
        # also plot first point out of loop to make appropriate legend
        plt.plot(points_x[0], points_y[0],marker="o",color="r",markerfacecolor="b",label="Legend label")
        for i in range(1,len(points_x)):
            plt.plot(points_x[i], points_y[i],marker="o",markerfacecolor="b")
        plt.legend(numpoints=1) #Only 1 point in legend because in CorelDraw "File is corrupted" if default two or more 
        pdf.savefig()
        plt.close()
    

    As a possible replacement for points (markers) pyplot.text can be used, for my example in question updated code looks like this:

    from matplotlib.backends.backend_pdf import PdfPages
    import matplotlib.pyplot as plt
    from matplotlib import rc
    rc("pdf", fonttype=42)
    
    with PdfPages("simple.pdf") as pdf:
        points_y = points_x = [1,2,3]
        plt.plot(points_x, points_y)
        # print points as + symbol
        for i in range(len(points_x)):
            plt.text(points_x[i], points_y[i],"+",ha="center", va="center")
        pdf.savefig()
        plt.close()