Matt Hancock
Matt Hancock

Reputation: 4039

Side-specific padding for matplotlib text bbox

Is it possible to specify the padding on a specific side of the bbox when adding text in matplotlib? I'm adding a LaTex table as text and for some reason the table is misaligned naturally with no padding specifications. I'd like to account for this for adding padding on the top of the bbox.

Unfortunately, there doesn't seem to be an option for adding padding to a specific side of a bbox. Is this possible?

Here's an example to illustrate:

import matplotlib
matplotlib.rc('text',usetex=True)
import matplotlib.pyplot as plt
import numpy as np

text = '\\begin{tabular}{|c|c|}\\hline 1 & 2 \\\\ \\hline 3 & 4 \\\\ \\hline \\end{tabular}'

plt.imshow(np.zeros((10,10)), cmap=plt.cm.gray)
plt.text( 4.5,
          4.5,
          text,
          fontsize=24,
          bbox=dict(fc='w',boxstyle='square,pad=0.5'), va='center', ha='center')
plt.axis('off')
plt.show()

Upvotes: 4

Views: 6271

Answers (1)

Matt Hancock
Matt Hancock

Reputation: 4039

I've found a workaround which is based on the answer suggested in this post. An easier solution would also be appreciated. I should also say that the vertical misalignment seems to happen only when I set usetex: True.

Here's the modified version of the above:

import matplotlib
matplotlib.rc('text',usetex=True)
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import numpy as np

text = '\\begin{tabular}{|c|c|}\\hline1&2\\\\\\hline3&4\\\\\\hline\\end{tabular}'

fig, ax = plt.subplots(1)

img = ax.imshow(np.zeros((10,10)), cmap=plt.cm.gray)
txt = ax.text( 4.5,
          4.5,
          text,
          fontsize=24,
          ha='center',
          va='center',
          bbox=dict(alpha=0))

fig.canvas.draw()
bbox = txt.get_bbox_patch()
xmin = bbox.get_window_extent().xmin
xmax = bbox.get_window_extent().xmax
ymin = bbox.get_window_extent().ymin
ymax = bbox.get_window_extent().ymax

xmin, ymin = fig.transFigure.inverted().transform((xmin, ymin))
xmax, ymax = fig.transFigure.inverted().transform((xmax, ymax))

dx = xmax-xmin
dy = ymax-ymin

# The bounding box vals can be tweaked manually here.
rect = Rectangle((xmin-0.02,ymin-0.01), dx+0.04, dy+0.05, fc='w', transform=fig.transFigure)

ax.add_patch(rect)
fig.canvas.draw()
ax.axis('off')
plt.savefig('ok.png',bbox_inches='tight')

This produces:

Upvotes: 1

Related Questions