How can I increase the quality of a matplotlib image (jpg) which is inserted into a MS Word document table?

  Kiến thức lập trình

I have a main Python module which creates a Word document with a table and then calls another module which creates and returns a simple cartesian plot of a polygon. The main module inserts the plot into a cell in the table and then loops to do it again. This is the main module:

import os
import random
from docx import Document
from docx.shared import Inches
from datetime import datetime
from docx.oxml import OxmlElement, ns
import Trapezoid_in_Cartesian_Grid_1
from PIL import Image
from pathlib import Path

doc = Document()

tbl = doc.add_table(rows=1, cols=0)
tbl.add_column(width=Inches(0.4))
tbl.add_column(width=Inches(3.0))
tbl.add_column(width=Inches(3.0))


def image_to_jpg(image_path):
    path = Path(image_path)
    if path.suffix not in {'.jpg', '.png', '.jfif', '.exif', '.gif', '.tiff', '.bmp'}:
        jpg_image_path = f'{path.parent / path.stem}_result.png'
        Image.open(image_path).convert('RGB').save(jpg_image_path, quality = 95)
        return jpg_image_path
    return image_path


for i in range(10):
    a = random.randint(-8,8)
    b = random.randint(-8,8)
    h = random.randint(-3,3)
    k = random.randint(-3,3)
    path = Trapezoid_in_Cartesian_Grid_1.ReflectTrap01OverXaxis(a,b,h,k)
    image_path = image_to_jpg(path)
    
    row = tbl.add_row()
    cell1 = tbl.cell(i,0)
    cell1.text = str(i+1) + "."
    cell2 = tbl.cell(i,1) 
    cell2.text = "Reflect the figure over the y-axis."
    cell3 = tbl.cell(i,2)
    paragraph = tbl.rows[i].cells[2].paragraphs[0]
    run = paragraph.add_run()
    run.add_picture(image_path)
   
# get current date and time and convert to string
current_datetime = datetime.now().strftime("%Y-%m-%d %H%M%S")
print("Current date & time : ", current_datetime)
str_current_datetime = str(current_datetime)
 
# create a file object along with extension
file_name = "WS_Proj " + str_current_datetime
header = doc.sections[0].header
header.paragraphs[0].text = file_name

doc.save(file_name + ".docx")

The module, function ReflectTrap01OverXaxis, which is called is:

from datetime import datetime
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.path import Path
import matplotlib.patches as patches
from matplotlib.ticker import MultipleLocator
from docx.shared import Inches
import matplotlib.ticker as ticker
import random

a = random.randint(-8,8)
b = random.randint(-8,8)
h = random.randint(3,6)
k = random.randint(3,6)

current_datetime = datetime.now().strftime("%Y-%m-%d %H%M%S")
str_current_datetime = str(current_datetime)


def ReflectTrap01OverXaxis(a,b,h,k):
       
   #Creates a polygon with certain vertices (verts1)
    verts1 = [(a,b),(a+h,b),(a+h,b-k),(a,b-k+1),(a,b)]
    codes1 = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]
    fig = plt.figure(figsize=(2.5,2.5))
    ax = fig.add_subplot(111)
    path1 = Path(verts1, codes1)
    patch1 = patches.PathPatch(path1, edgecolor = "black", facecolor = "None", lw=0.8, zorder = 3)
    ax.add_patch(patch1)
    
   #Sets x and y axes
    ax.set_xlim(-12,12)
    ax.set_ylim(-12,12)
    plt.grid(True)
    plt.tick_params(labelsize = 6)
    plt.xlabel(None, fontsize = 9)
   #Determines the size of the plot
    plt.rcParams["figure.figsize"] = [3,3]
    
    
    plt.axhline(color = "black")
    plt.axvline(color = "black")
    
    ax.grid(which = "both",color = "black", linewidth=0.5)
    ax.minorticks_on()
    
   #Creates a unique file name with date and time
    current_datetime = datetime.now().strftime("%Y-%m-%d %H%M%S")
    str_current_datetime = str(current_datetime)
    file_name = "fig1 " + str_current_datetime
    plt.savefig(file_name, format = "png")
    
    return file_name

The quality of the jpg inserted into the table is too low. I’ve researched here and elsewhere and I’ve tried different image file formats such as svg and pdf. I’ve also tried changing the dpi. When I increase the dpi the quality goes up but the image size does also and the image must fit in a table column which is 3 inches wide. Thanks in advance.

LEAVE A COMMENT