Python 3.9.0 Matplotlib 3.5.1
I drew a table and merged cells by this method. However the output in MPL figure looks good but if I save it as SVG format, then it becomes weird. Additionally, when I convert the file into EMF format through Inkscape, it becomes worse. How can I save the figure as SVG format as it is shown in the figure handle? (bitmap formats-jpg, png, ..- have no problem)
Reproducible Code
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
def mergecells(table, cells):
'''
Merge N matplotlib.Table cells
Parameters
-----------
table: matplotlib.Table
the table
cells: list[set]
list of sets od the table coordinates
- example: [(0,1), (0,0), (0,2)]
Notes
------
https://stackoverflow.com/a/53819765/12684122
'''
cells_array = [np.asarray(c) for c in cells]
h = np.array([cells_array[i+1][0] - cells_array[i][0] for i in range(len(cells_array) - 1)])
v = np.array([cells_array[i+1][1] - cells_array[i][1] for i in range(len(cells_array) - 1)])
# if it's a horizontal merge, all values for `h` are 0
if not np.any(h):
# sort by horizontal coord
cells = np.array(sorted(list(cells), key=lambda v: v[1]))
edges = ['BTL'] + ['BT' for i in range(len(cells) - 2)] + ['BTR']
elif not np.any(v):
cells = np.array(sorted(list(cells), key=lambda h: h[0]))
edges = ['TRL'] + ['RL' for i in range(len(cells) - 2)] + ['BRL']
else:
raise ValueError("Only horizontal and vertical merges allowed")
for cell, e in zip(cells, edges):
table[cell[0], cell[1]].visible_edges = e
txts = [table[cell[0], cell[1]].get_text() for cell in cells]
tpos = [np.array(t.get_position()) for t in txts]
# transpose the text of the left cell
trans = (tpos[-1] - tpos[0])/2
# didn't had to check for ha because I only want ha='center'
txts[0].set_transform(mpl.transforms.Affine2D().translate(*trans))
for txt in txts[1:]:
txt.set_visible(False)
df = pd.DataFrame()
df['Animal'] = ['Cow', 'Bear']
df['Weight'] = [250, 450]
df['Favorite'] = ['Grass', 'Honey']
df['Least Favorite'] = ['Meat', 'Leaves']
fig = plt.figure(figsize=(9,2))
ax=fig.gca()
ax.axis('off')
r,c = df.shape
# plot the real table
table = ax.table(cellText=np.vstack([df.columns, df.values]),
cellColours=[['none']*c]*(r+1),
bbox=[0, 0, 1, 1],
cellLoc="center")
# need to draw here so the text positions are calculated
fig.canvas.draw()
mergecells(table, [(0,0),(1,0),(2,0)])
fig.savefig("svgoutput.svg")
plt.show()
Image shown in MPL figure handle
Image shown in the saved SVG file
You can see the text in merged cells ("Animal") goes down. Though I have not attached the EMF file, it goes further down and even some texts disappeared.