My question is a kind of follow up of this question. I use the solution proposed in the accepted answer to put some images as tick labels:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.image import BboxImage,imread
from matplotlib.transforms import Bbox
# define where to put symbols vertically
TICKYPOS = -.6
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10))
plt.xlim((0,10))
plt.ylim((0,10))
# Remove tick labels
ax.get_xaxis().set_ticklabels([])
# Go from data coordinates to display coordinates
lowerCorner = ax.transData.transform((.8,TICKYPOS-.2))
upperCorner = ax.transData.transform((1.2,TICKYPOS+.2))
bbox_image = BboxImage(Bbox([lowerCorner,upperCorner]),
norm = None,
origin=None,
clip_on=False)
bbox_image.set_data(imread('thumb.png'))
ax.add_artist(bbox_image)
where thumb.png is an example of image I want to put as a tick label.
I then save the image with plt.savefig("bbox_large.png")
and it works perfectly:
Unfortunately there is a lot of white space remaining around the picture. I tried to remove it using plt.savefig("bbox_tight.png",bbox_inches='tight')
. However the positioning gets messed up:
As far as my understanding of matplotlib goes, the problem is that the bbox_inches='tight'
option of savefig
actually changes the display coordinates system, that is the origin is not in the same place. The figure is somehow correctly displayed but it seems that the coordinates of the artists added to the axes are not automatically updated.
I tried to take the extra artists into account using:
plt.savefig("bbox_tight_extra.png",bbox_extra_artists=[bbox_image],bbox_inches='tight')
but it gives the same result.
I also tried to use the event manager to manually update the display coordinates:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.image import BboxImage,imread
from matplotlib.transforms import Bbox
def ondraw(event):
# Go from data coordinates to display coordinates
lowerCorner = ax.transData.transform((.8,TICKYPOS-.2))
upperCorner = ax.transData.transform((1.2,TICKYPOS+.2))
bbox_image = BboxImage(Bbox([lowerCorner,upperCorner]),
norm = None,
origin=None,
clip_on=False)
bbox_image.set_data(imread('thumb.png'))
ax.add_artist(bbox_image)
# define where to put symbols vertically
TICKYPOS = -.6
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10))
plt.xlim((0,10))
plt.ylim((0,10))
# Remove tick labels
ax.get_xaxis().set_ticklabels([])
fig.canvas.mpl_connect('draw_event', ondraw)
but it also gives the same result. I assume that it is because I do not explicitly use the event
variable and hence I do not use the updated display coordinate system, that is the transData
that I use is not the correct one.
How can I avoid having the position of the images getting messed up with bbox_inches='tight'
?